xref: /freebsd/contrib/sendmail/src/recipient.c (revision 11afcc8f9f96d657b8e6f7547c02c1957331fc96)
1 /*
2  * Copyright (c) 1998 Sendmail, Inc.  All rights reserved.
3  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
4  * Copyright (c) 1988, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * By using this file, you agree to the terms and conditions set
8  * forth in the LICENSE file which can be found at the top level of
9  * the sendmail distribution.
10  *
11  */
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)recipient.c	8.154 (Berkeley) 6/24/98";
15 #endif /* not lint */
16 
17 # include "sendmail.h"
18 # include <grp.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 **		aliaslevel -- the current alias nesting depth -- to
35 **			diagnose loops.
36 **		e -- the envelope in which to add these recipients.
37 **
38 **	Returns:
39 **		The number of addresses actually on the list.
40 **
41 **	Side Effects:
42 **		none.
43 */
44 
45 /* q_flags bits inherited from ctladdr */
46 #define QINHERITEDBITS	(QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY|QHASNOTIFY)
47 
48 int
49 sendtolist(list, ctladdr, sendq, aliaslevel, e)
50 	char *list;
51 	ADDRESS *ctladdr;
52 	ADDRESS **sendq;
53 	int aliaslevel;
54 	register ENVELOPE *e;
55 {
56 	register char *p;
57 	register ADDRESS *al;	/* list of addresses to send to */
58 	char delimiter;		/* the address delimiter */
59 	int naddrs;
60 	int i;
61 	char *oldto = e->e_to;
62 	char *bufp;
63 	char buf[MAXNAME + 1];
64 
65 	if (list == NULL)
66 	{
67 		syserr("sendtolist: null list");
68 		return 0;
69 	}
70 
71 	if (tTd(25, 1))
72 	{
73 		printf("sendto: %s\n   ctladdr=", list);
74 		printaddr(ctladdr, FALSE);
75 	}
76 
77 	/* heuristic to determine old versus new style addresses */
78 	if (ctladdr == NULL &&
79 	    (strchr(list, ',') != NULL || strchr(list, ';') != NULL ||
80 	     strchr(list, '<') != NULL || strchr(list, '(') != NULL))
81 		e->e_flags &= ~EF_OLDSTYLE;
82 	delimiter = ' ';
83 	if (!bitset(EF_OLDSTYLE, e->e_flags) || ctladdr != NULL)
84 		delimiter = ',';
85 
86 	al = NULL;
87 	naddrs = 0;
88 
89 	/* make sure we have enough space to copy the string */
90 	i = strlen(list) + 1;
91 	if (i <= sizeof buf)
92 		bufp = buf;
93 	else
94 		bufp = xalloc(i);
95 	strcpy(bufp, denlstring(list, FALSE, TRUE));
96 
97 	for (p = bufp; *p != '\0'; )
98 	{
99 		auto char *delimptr;
100 		register ADDRESS *a;
101 
102 		/* parse the address */
103 		while ((isascii(*p) && isspace(*p)) || *p == ',')
104 			p++;
105 		a = parseaddr(p, NULLADDR, RF_COPYALL, delimiter, &delimptr, e);
106 		p = delimptr;
107 		if (a == NULL)
108 			continue;
109 		a->q_next = al;
110 		a->q_alias = ctladdr;
111 
112 		/* arrange to inherit attributes from parent */
113 		if (ctladdr != NULL)
114 		{
115 			ADDRESS *b;
116 			extern ADDRESS *self_reference __P((ADDRESS *, ENVELOPE *));
117 
118 			/* self reference test */
119 			if (sameaddr(ctladdr, a))
120 			{
121 				if (tTd(27, 5))
122 				{
123 					printf("sendtolist: QSELFREF ");
124 					printaddr(ctladdr, FALSE);
125 				}
126 				ctladdr->q_flags |= QSELFREF;
127 			}
128 
129 			/* check for address loops */
130 			b = self_reference(a, e);
131 			if (b != NULL)
132 			{
133 				b->q_flags |= QSELFREF;
134 				if (tTd(27, 5))
135 				{
136 					printf("sendtolist: QSELFREF ");
137 					printaddr(b, FALSE);
138 				}
139 				if (a != b)
140 				{
141 					if (tTd(27, 5))
142 					{
143 						printf("sendtolist: QDONTSEND ");
144 						printaddr(a, FALSE);
145 					}
146 					a->q_flags |= QDONTSEND;
147 					b->q_flags |= a->q_flags & QNOTREMOTE;
148 					continue;
149 				}
150 			}
151 
152 			/* full name */
153 			if (a->q_fullname == NULL)
154 				a->q_fullname = ctladdr->q_fullname;
155 
156 			/* various flag bits */
157 			a->q_flags &= ~QINHERITEDBITS;
158 			a->q_flags |= ctladdr->q_flags & QINHERITEDBITS;
159 
160 			/* original recipient information */
161 			a->q_orcpt = ctladdr->q_orcpt;
162 		}
163 
164 		al = a;
165 	}
166 
167 	/* arrange to send to everyone on the local send list */
168 	while (al != NULL)
169 	{
170 		register ADDRESS *a = al;
171 
172 		al = a->q_next;
173 		a = recipient(a, sendq, aliaslevel, e);
174 		naddrs++;
175 	}
176 
177 	e->e_to = oldto;
178 	if (bufp != buf)
179 		free(bufp);
180 	return (naddrs);
181 }
182 /*
183 **  RECIPIENT -- Designate a message recipient
184 **
185 **	Saves the named person for future mailing.
186 **
187 **	Parameters:
188 **		a -- the (preparsed) address header for the recipient.
189 **		sendq -- a pointer to the head of a queue to put the
190 **			recipient in.  Duplicate supression is done
191 **			in this queue.
192 **		aliaslevel -- the current alias nesting depth.
193 **		e -- the current envelope.
194 **
195 **	Returns:
196 **		The actual address in the queue.  This will be "a" if
197 **		the address is not a duplicate, else the original address.
198 **
199 **	Side Effects:
200 **		none.
201 */
202 
203 ADDRESS *
204 recipient(a, sendq, aliaslevel, e)
205 	register ADDRESS *a;
206 	register ADDRESS **sendq;
207 	int aliaslevel;
208 	register ENVELOPE *e;
209 {
210 	register ADDRESS *q;
211 	ADDRESS **pq;
212 	register struct mailer *m;
213 	register char *p;
214 	bool quoted = FALSE;		/* set if the addr has a quote bit */
215 	int findusercount = 0;
216 	bool initialdontsend = bitset(QDONTSEND, a->q_flags);
217 	int i;
218 	char *buf;
219 	char buf0[MAXNAME + 1];		/* unquoted image of the user name */
220 	extern void alias __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
221 
222 	e->e_to = a->q_paddr;
223 	m = a->q_mailer;
224 	errno = 0;
225 	if (aliaslevel == 0)
226 		a->q_flags |= QPRIMARY;
227 	if (tTd(26, 1))
228 	{
229 		printf("\nrecipient (%d): ", aliaslevel);
230 		printaddr(a, FALSE);
231 	}
232 
233 	/* if this is primary, add it to the original recipient list */
234 	if (a->q_alias == NULL)
235 	{
236 		if (e->e_origrcpt == NULL)
237 			e->e_origrcpt = a->q_paddr;
238 		else if (e->e_origrcpt != a->q_paddr)
239 			e->e_origrcpt = "";
240 	}
241 
242 	/* break aliasing loops */
243 	if (aliaslevel > MaxAliasRecursion)
244 	{
245 		a->q_flags |= QBADADDR;
246 		a->q_status = "5.4.6";
247 		usrerr("554 aliasing/forwarding loop broken (%d aliases deep; %d max)",
248 			aliaslevel, MaxAliasRecursion);
249 		return (a);
250 	}
251 
252 	/*
253 	**  Finish setting up address structure.
254 	*/
255 
256 	/* get unquoted user for file, program or user.name check */
257 	i = strlen(a->q_user);
258 	if (i >= sizeof buf0)
259 		buf = xalloc(i + 1);
260 	else
261 		buf = buf0;
262 	(void) strcpy(buf, a->q_user);
263 	for (p = buf; *p != '\0' && !quoted; p++)
264 	{
265 		if (*p == '\\')
266 			quoted = TRUE;
267 	}
268 	stripquotes(buf);
269 
270 	/* check for direct mailing to restricted mailers */
271 	if (m == ProgMailer)
272 	{
273 		if (a->q_alias == NULL)
274 		{
275 			a->q_flags |= QBADADDR;
276 			a->q_status = "5.7.1";
277 			usrerr("550 Cannot mail directly to programs");
278 		}
279 		else if (bitset(QBOGUSSHELL, a->q_alias->q_flags))
280 		{
281 			a->q_flags |= QBADADDR;
282 			a->q_status = "5.7.1";
283 			if (a->q_alias->q_ruser == NULL)
284 				usrerr("550 UID %d is an unknown user: cannot mail to programs",
285 					a->q_alias->q_uid);
286 			else
287 				usrerr("550 User %s@%s doesn't have a valid shell for mailing to programs",
288 					a->q_alias->q_ruser, MyHostName);
289 		}
290 		else if (bitset(QUNSAFEADDR, a->q_alias->q_flags))
291 		{
292 			a->q_flags |= QBADADDR;
293 			a->q_status = "5.7.1";
294 			a->q_rstatus = newstr("Unsafe for mailing to programs");
295 			usrerr("550 Address %s is unsafe for mailing to programs",
296 				a->q_alias->q_paddr);
297 		}
298 	}
299 
300 	/*
301 	**  Look up this person in the recipient list.
302 	**	If they are there already, return, otherwise continue.
303 	**	If the list is empty, just add it.  Notice the cute
304 	**	hack to make from addresses suppress things correctly:
305 	**	the QDONTSEND bit will be set in the send list.
306 	**	[Please note: the emphasis is on "hack."]
307 	*/
308 
309 	for (pq = sendq; (q = *pq) != NULL; pq = &q->q_next)
310 	{
311 		if (sameaddr(q, a) &&
312 		    (bitset(QRCPTOK, q->q_flags) ||
313 		     !bitset(QPRIMARY, q->q_flags)))
314 		{
315 			if (tTd(26, 1))
316 			{
317 				printf("%s in sendq: ", a->q_paddr);
318 				printaddr(q, FALSE);
319 			}
320 			if (!bitset(QPRIMARY, q->q_flags))
321 			{
322 				if (!bitset(QDONTSEND, a->q_flags))
323 					message("duplicate suppressed");
324 				q->q_flags |= a->q_flags;
325 			}
326 			else if (bitset(QSELFREF, q->q_flags))
327 				q->q_flags |= a->q_flags & ~QDONTSEND;
328 			a = q;
329 			goto done;
330 		}
331 	}
332 
333 	/* add address on list */
334 	*pq = a;
335 	a->q_next = NULL;
336 
337 	/*
338 	**  Alias the name and handle special mailer types.
339 	*/
340 
341   trylocaluser:
342 	if (tTd(29, 7))
343 		printf("at trylocaluser %s\n", a->q_user);
344 
345 	if (bitset(QDONTSEND|QBADADDR|QVERIFIED, a->q_flags))
346 		goto testselfdestruct;
347 
348 	if (m == InclMailer)
349 	{
350 		a->q_flags |= QDONTSEND;
351 		if (a->q_alias == NULL)
352 		{
353 			a->q_flags |= QBADADDR;
354 			a->q_status = "5.7.1";
355 			usrerr("550 Cannot mail directly to :include:s");
356 		}
357 		else
358 		{
359 			int ret;
360 
361 			message("including file %s", a->q_user);
362 			ret = include(a->q_user, FALSE, a, sendq, aliaslevel, e);
363 			if (transienterror(ret))
364 			{
365 				if (LogLevel > 2)
366 					sm_syslog(LOG_ERR, e->e_id,
367 						"include %s: transient error: %s",
368 						shortenstring(a->q_user, MAXSHORTSTR),
369 						errstring(ret));
370 				a->q_flags |= QQUEUEUP;
371 				a->q_flags &= ~QDONTSEND;
372 				usrerr("451 Cannot open %s: %s",
373 					shortenstring(a->q_user, MAXSHORTSTR),
374 					errstring(ret));
375 			}
376 			else if (ret != 0)
377 			{
378 				a->q_flags |= QBADADDR;
379 				a->q_status = "5.2.4";
380 				usrerr("550 Cannot open %s: %s",
381 					shortenstring(a->q_user, MAXSHORTSTR),
382 					errstring(ret));
383 			}
384 		}
385 	}
386 	else if (m == FileMailer)
387 	{
388 		extern bool writable __P((char *, ADDRESS *, int));
389 
390 		/* check if writable or creatable */
391 		if (a->q_alias == NULL)
392 		{
393 			a->q_flags |= QBADADDR;
394 			a->q_status = "5.7.1";
395 			usrerr("550 Cannot mail directly to files");
396 		}
397 		else if (bitset(QBOGUSSHELL, a->q_alias->q_flags))
398 		{
399 			a->q_flags |= QBADADDR;
400 			a->q_status = "5.7.1";
401 			if (a->q_alias->q_ruser == NULL)
402 				usrerr("550 UID %d is an unknown user: cannot mail to files",
403 					a->q_alias->q_uid);
404 			else
405 				usrerr("550 User %s@%s doesn't have a valid shell for mailing to files",
406 					a->q_alias->q_ruser, MyHostName);
407 		}
408 		else if (bitset(QUNSAFEADDR, a->q_alias->q_flags))
409 		{
410 			a->q_flags |= QBADADDR;
411 			a->q_status = "5.7.1";
412 			a->q_rstatus = newstr("Unsafe for mailing to files");
413 			usrerr("550 Address %s is unsafe for mailing to files",
414 				a->q_alias->q_paddr);
415 		}
416 		else if (strcmp(buf, "/dev/null") == 0)
417 		{
418 			/* /dev/null is always accepted */
419 		}
420 		else if (!writable(buf, a->q_alias, SFF_CREAT))
421 		{
422 			a->q_flags |= QBADADDR;
423 			giveresponse(EX_CANTCREAT, m, NULL, a->q_alias,
424 				     (time_t) 0, e);
425 		}
426 	}
427 
428 	/* try aliasing */
429 	if (!quoted && !bitset(QDONTSEND, a->q_flags) &&
430 	    bitnset(M_ALIASABLE, m->m_flags))
431 		alias(a, sendq, aliaslevel, e);
432 
433 # if USERDB
434 	/* if not aliased, look it up in the user database */
435 	if (!bitset(QDONTSEND|QNOTREMOTE|QVERIFIED, a->q_flags) &&
436 	    bitnset(M_CHECKUDB, m->m_flags))
437 	{
438 		extern int udbexpand __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
439 
440 		if (udbexpand(a, sendq, aliaslevel, e) == EX_TEMPFAIL)
441 		{
442 			a->q_flags |= QQUEUEUP;
443 			if (e->e_message == NULL)
444 				e->e_message = newstr("Deferred: user database error");
445 			if (LogLevel > 8)
446 				sm_syslog(LOG_INFO, e->e_id,
447 					"deferred: udbexpand: %s",
448 					errstring(errno));
449 			message("queued (user database error): %s",
450 				errstring(errno));
451 			e->e_nrcpts++;
452 			goto testselfdestruct;
453 		}
454 	}
455 # endif
456 
457 	/*
458 	**  If we have a level two config file, then pass the name through
459 	**  Ruleset 5 before sending it off.  Ruleset 5 has the right
460 	**  to send rewrite it to another mailer.  This gives us a hook
461 	**  after local aliasing has been done.
462 	*/
463 
464 	if (tTd(29, 5))
465 	{
466 		printf("recipient: testing local?  cl=%d, rr5=%lx\n\t",
467 			ConfigLevel, (u_long) RewriteRules[5]);
468 		printaddr(a, FALSE);
469 	}
470 	if (!bitset(QNOTREMOTE|QDONTSEND|QQUEUEUP|QVERIFIED, a->q_flags) &&
471 	    ConfigLevel >= 2 && RewriteRules[5] != NULL &&
472 	    bitnset(M_TRYRULESET5, m->m_flags))
473 	{
474 		extern void maplocaluser __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
475 
476 		maplocaluser(a, sendq, aliaslevel + 1, e);
477 	}
478 
479 	/*
480 	**  If it didn't get rewritten to another mailer, go ahead
481 	**  and deliver it.
482 	*/
483 
484 	if (!bitset(QDONTSEND|QQUEUEUP|QVERIFIED, a->q_flags) &&
485 	    bitnset(M_HASPWENT, m->m_flags))
486 	{
487 		auto bool fuzzy;
488 		register struct passwd *pw;
489 		extern void forward __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
490 
491 		/* warning -- finduser may trash buf */
492 		pw = finduser(buf, &fuzzy);
493 		if (pw == NULL || strlen(pw->pw_name) > MAXNAME)
494 		{
495 			a->q_flags |= QBADADDR;
496 			a->q_status = "5.1.1";
497 			giveresponse(EX_NOUSER, m, NULL, a->q_alias,
498 				     (time_t) 0, e);
499 		}
500 		else
501 		{
502 			char nbuf[MAXNAME + 1];
503 
504 			if (fuzzy)
505 			{
506 				/* name was a fuzzy match */
507 				a->q_user = newstr(pw->pw_name);
508 				if (findusercount++ > 3)
509 				{
510 					a->q_flags |= QBADADDR;
511 					a->q_status = "5.4.6";
512 					usrerr("554 aliasing/forwarding loop for %s broken",
513 						pw->pw_name);
514 					goto done;
515 				}
516 
517 				/* see if it aliases */
518 				(void) strcpy(buf, pw->pw_name);
519 				goto trylocaluser;
520 			}
521 			if (strcmp(pw->pw_dir, "/") == 0)
522 				a->q_home = "";
523 			else
524 				a->q_home = newstr(pw->pw_dir);
525 			a->q_uid = pw->pw_uid;
526 			a->q_gid = pw->pw_gid;
527 			a->q_ruser = newstr(pw->pw_name);
528 			a->q_flags |= QGOODUID;
529 			buildfname(pw->pw_gecos, pw->pw_name, nbuf, sizeof nbuf);
530 			if (nbuf[0] != '\0')
531 				a->q_fullname = newstr(nbuf);
532 			if (!usershellok(pw->pw_name, pw->pw_shell))
533 			{
534 				a->q_flags |= QBOGUSSHELL;
535 			}
536 			if (bitset(EF_VRFYONLY, e->e_flags))
537 			{
538 				/* don't do any more now */
539 				a->q_flags |= QVERIFIED;
540 			}
541 			else if (!quoted)
542 				forward(a, sendq, aliaslevel, e);
543 		}
544 	}
545 	if (!bitset(QDONTSEND, a->q_flags))
546 		e->e_nrcpts++;
547 
548   testselfdestruct:
549 	a->q_flags |= QTHISPASS;
550 	if (tTd(26, 8))
551 	{
552 		printf("testselfdestruct: ");
553 		printaddr(a, FALSE);
554 		if (tTd(26, 10))
555 		{
556 			printf("SENDQ:\n");
557 			printaddr(*sendq, TRUE);
558 			printf("----\n");
559 		}
560 	}
561 	if (a->q_alias == NULL && a != &e->e_from &&
562 	    bitset(QDONTSEND, a->q_flags))
563 	{
564 		for (q = *sendq; q != NULL; q = q->q_next)
565 		{
566 			if (!bitset(QDONTSEND, q->q_flags))
567 				break;
568 		}
569 		if (q == NULL)
570 		{
571 			a->q_flags |= QBADADDR;
572 			a->q_status = "5.4.6";
573 			usrerr("554 aliasing/forwarding loop broken");
574 		}
575 	}
576 
577   done:
578 	a->q_flags |= QTHISPASS;
579 	if (buf != buf0)
580 		free(buf);
581 
582 	/*
583 	**  If we are at the top level, check to see if this has
584 	**  expanded to exactly one address.  If so, it can inherit
585 	**  the primaryness of the address.
586 	**
587 	**  While we're at it, clear the QTHISPASS bits.
588 	*/
589 
590 	if (aliaslevel == 0)
591 	{
592 		int nrcpts = 0;
593 		ADDRESS *only = NULL;
594 
595 		for (q = *sendq; q != NULL; q = q->q_next)
596 		{
597 			if (bitset(QTHISPASS, q->q_flags) &&
598 			    !bitset(QDONTSEND|QBADADDR, q->q_flags))
599 			{
600 				nrcpts++;
601 				only = q;
602 			}
603 			q->q_flags &= ~QTHISPASS;
604 		}
605 		if (nrcpts == 1)
606 		{
607 			/* check to see if this actually got a new owner */
608 			q = only;
609 			while ((q = q->q_alias) != NULL)
610 			{
611 				if (q->q_owner != NULL)
612 					break;
613 			}
614 			if (q == NULL)
615 				only->q_flags |= QPRIMARY;
616 		}
617 		else if (!initialdontsend && nrcpts > 0)
618 		{
619 			/* arrange for return receipt */
620 			e->e_flags |= EF_SENDRECEIPT;
621 			a->q_flags |= QEXPANDED;
622 			if (e->e_xfp != NULL && bitset(QPINGONSUCCESS, a->q_flags))
623 				fprintf(e->e_xfp,
624 					"%s... expanded to multiple addresses\n",
625 					a->q_paddr);
626 		}
627 	}
628 	a->q_flags |= QRCPTOK;
629 	return (a);
630 }
631 /*
632 **  FINDUSER -- find the password entry for a user.
633 **
634 **	This looks a lot like getpwnam, except that it may want to
635 **	do some fancier pattern matching in /etc/passwd.
636 **
637 **	This routine contains most of the time of many sendmail runs.
638 **	It deserves to be optimized.
639 **
640 **	Parameters:
641 **		name -- the name to match against.
642 **		fuzzyp -- an outarg that is set to TRUE if this entry
643 **			was found using the fuzzy matching algorithm;
644 **			set to FALSE otherwise.
645 **
646 **	Returns:
647 **		A pointer to a pw struct.
648 **		NULL if name is unknown or ambiguous.
649 **
650 **	Side Effects:
651 **		may modify name.
652 */
653 
654 struct passwd *
655 finduser(name, fuzzyp)
656 	char *name;
657 	bool *fuzzyp;
658 {
659 	register struct passwd *pw;
660 	register char *p;
661 	bool tryagain;
662 
663 	if (tTd(29, 4))
664 		printf("finduser(%s): ", name);
665 
666 	*fuzzyp = FALSE;
667 
668 #ifdef HESIOD
669 	/* DEC Hesiod getpwnam accepts numeric strings -- short circuit it */
670 	for (p = name; *p != '\0'; p++)
671 		if (!isascii(*p) || !isdigit(*p))
672 			break;
673 	if (*p == '\0')
674 	{
675 		if (tTd(29, 4))
676 			printf("failed (numeric input)\n");
677 		return NULL;
678 	}
679 #endif
680 
681 	/* look up this login name using fast path */
682 	if ((pw = sm_getpwnam(name)) != NULL)
683 	{
684 		if (tTd(29, 4))
685 			printf("found (non-fuzzy)\n");
686 		return (pw);
687 	}
688 
689 	/* try mapping it to lower case */
690 	tryagain = FALSE;
691 	for (p = name; *p != '\0'; p++)
692 	{
693 		if (isascii(*p) && isupper(*p))
694 		{
695 			*p = tolower(*p);
696 			tryagain = TRUE;
697 		}
698 	}
699 	if (tryagain && (pw = sm_getpwnam(name)) != NULL)
700 	{
701 		if (tTd(29, 4))
702 			printf("found (lower case)\n");
703 		*fuzzyp = TRUE;
704 		return pw;
705 	}
706 
707 #if MATCHGECOS
708 	/* see if fuzzy matching allowed */
709 	if (!MatchGecos)
710 	{
711 		if (tTd(29, 4))
712 			printf("not found (fuzzy disabled)\n");
713 		return NULL;
714 	}
715 
716 	/* search for a matching full name instead */
717 	for (p = name; *p != '\0'; p++)
718 	{
719 		if (*p == (SpaceSub & 0177) || *p == '_')
720 			*p = ' ';
721 	}
722 	(void) setpwent();
723 	while ((pw = getpwent()) != NULL)
724 	{
725 		char buf[MAXNAME + 1];
726 
727 # if 0
728 		if (strcasecmp(pw->pw_name, name) == 0)
729 		{
730 			if (tTd(29, 4))
731 				printf("found (case wrapped)\n");
732 			break;
733 		}
734 # endif
735 
736 		buildfname(pw->pw_gecos, pw->pw_name, buf, sizeof buf);
737 		if (strchr(buf, ' ') != NULL && !strcasecmp(buf, name))
738 		{
739 			if (tTd(29, 4))
740 				printf("fuzzy matches %s\n", pw->pw_name);
741 			message("sending to login name %s", pw->pw_name);
742 			break;
743 		}
744 	}
745 	if (pw != NULL)
746 		*fuzzyp = TRUE;
747 	else if (tTd(29, 4))
748 		printf("no fuzzy match found\n");
749 # if DEC_OSF_BROKEN_GETPWENT	/* DEC OSF/1 3.2 or earlier */
750 	endpwent();
751 # endif
752 	return pw;
753 #else
754 	if (tTd(29, 4))
755 		printf("not found (fuzzy disabled)\n");
756 	return NULL;
757 #endif
758 }
759 /*
760 **  WRITABLE -- predicate returning if the file is writable.
761 **
762 **	This routine must duplicate the algorithm in sys/fio.c.
763 **	Unfortunately, we cannot use the access call since we
764 **	won't necessarily be the real uid when we try to
765 **	actually open the file.
766 **
767 **	Notice that ANY file with ANY execute bit is automatically
768 **	not writable.  This is also enforced by mailfile.
769 **
770 **	Parameters:
771 **		filename -- the file name to check.
772 **		ctladdr -- the controlling address for this file.
773 **		flags -- SFF_* flags to control the function.
774 **
775 **	Returns:
776 **		TRUE -- if we will be able to write this file.
777 **		FALSE -- if we cannot write this file.
778 **
779 **	Side Effects:
780 **		none.
781 */
782 
783 bool
784 writable(filename, ctladdr, flags)
785 	char *filename;
786 	ADDRESS *ctladdr;
787 	int flags;
788 {
789 	uid_t euid;
790 	gid_t egid;
791 	char *uname;
792 
793 	if (tTd(44, 5))
794 		printf("writable(%s, 0x%x)\n", filename, flags);
795 
796 	/*
797 	**  File does exist -- check that it is writable.
798 	*/
799 
800 	if (geteuid() != 0)
801 	{
802 		euid = geteuid();
803 		egid = getegid();
804 		uname = NULL;
805 	}
806 	else if (ctladdr != NULL)
807 	{
808 		euid = ctladdr->q_uid;
809 		egid = ctladdr->q_gid;
810 		uname = ctladdr->q_user;
811 	}
812 	else if (bitset(SFF_RUNASREALUID, flags))
813 	{
814 		euid = RealUid;
815 		egid = RealGid;
816 		uname = RealUserName;
817 	}
818 	else if (FileMailer != NULL && !bitset(SFF_ROOTOK, flags))
819 	{
820 		euid = FileMailer->m_uid;
821 		egid = FileMailer->m_gid;
822 		uname = NULL;
823 	}
824 	else
825 	{
826 		euid = egid = 0;
827 		uname = NULL;
828 	}
829 	if (!bitset(SFF_ROOTOK, flags))
830 	{
831 		if (euid == 0)
832 		{
833 			euid = DefUid;
834 			uname = DefUser;
835 		}
836 		if (egid == 0)
837 			egid = DefGid;
838 	}
839 	if (geteuid() == 0 &&
840 	    (ctladdr == NULL || !bitset(QGOODUID, ctladdr->q_flags)))
841 		flags |= SFF_SETUIDOK;
842 
843 	if (!bitset(DBS_FILEDELIVERYTOSYMLINK, DontBlameSendmail))
844 		flags |= SFF_NOSLINK;
845 	if (!bitset(DBS_FILEDELIVERYTOHARDLINK, DontBlameSendmail))
846 		flags |= SFF_NOHLINK;
847 
848 	errno = safefile(filename, euid, egid, uname, flags, S_IWRITE, NULL);
849 	return errno == 0;
850 }
851 /*
852 **  INCLUDE -- handle :include: specification.
853 **
854 **	Parameters:
855 **		fname -- filename to include.
856 **		forwarding -- if TRUE, we are reading a .forward file.
857 **			if FALSE, it's a :include: file.
858 **		ctladdr -- address template to use to fill in these
859 **			addresses -- effective user/group id are
860 **			the important things.
861 **		sendq -- a pointer to the head of the send queue
862 **			to put these addresses in.
863 **		aliaslevel -- the alias nesting depth.
864 **		e -- the current envelope.
865 **
866 **	Returns:
867 **		open error status
868 **
869 **	Side Effects:
870 **		reads the :include: file and sends to everyone
871 **		listed in that file.
872 **
873 **	Security Note:
874 **		If you have restricted chown (that is, you can't
875 **		give a file away), it is reasonable to allow programs
876 **		and files called from this :include: file to be to be
877 **		run as the owner of the :include: file.  This is bogus
878 **		if there is any chance of someone giving away a file.
879 **		We assume that pre-POSIX systems can give away files.
880 **
881 **		There is an additional restriction that if you
882 **		forward to a :include: file, it will not take on
883 **		the ownership of the :include: file.  This may not
884 **		be necessary, but shouldn't hurt.
885 */
886 
887 static jmp_buf	CtxIncludeTimeout;
888 static void	includetimeout __P((void));
889 
890 int
891 include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
892 	char *fname;
893 	bool forwarding;
894 	ADDRESS *ctladdr;
895 	ADDRESS **sendq;
896 	int aliaslevel;
897 	ENVELOPE *e;
898 {
899 	FILE *volatile fp = NULL;
900 	char *oldto = e->e_to;
901 	char *oldfilename = FileName;
902 	int oldlinenumber = LineNumber;
903 	register EVENT *ev = NULL;
904 	int nincludes;
905 	int mode;
906 	register ADDRESS *ca;
907 	volatile uid_t saveduid, uid;
908 	volatile gid_t savedgid, gid;
909 	char *volatile uname;
910 	int rval = 0;
911 	volatile int sfflags = SFF_REGONLY;
912 	register char *p;
913 	bool safechown = FALSE;
914 	volatile bool safedir = FALSE;
915 	struct stat st;
916 	char buf[MAXLINE];
917 	extern bool chownsafe __P((int, bool));
918 
919 	if (tTd(27, 2))
920 		printf("include(%s)\n", fname);
921 	if (tTd(27, 4))
922 		printf("   ruid=%d euid=%d\n", (int) getuid(), (int) geteuid());
923 	if (tTd(27, 14))
924 	{
925 		printf("ctladdr ");
926 		printaddr(ctladdr, FALSE);
927 	}
928 
929 	if (tTd(27, 9))
930 		printf("include: old uid = %d/%d\n",
931 		       (int) getuid(), (int) geteuid());
932 
933 	if (forwarding)
934 		sfflags |= SFF_MUSTOWN|SFF_ROOTOK|SFF_NOSLINK;
935 
936 	ca = getctladdr(ctladdr);
937 	if (ca == NULL)
938 	{
939 		uid = DefUid;
940 		gid = DefGid;
941 		uname = DefUser;
942 	}
943 	else
944 	{
945 		uid = ca->q_uid;
946 		gid = ca->q_gid;
947 		uname = ca->q_user;
948 	}
949 #if HASSETREUID || USESETEUID
950 	saveduid = geteuid();
951 	savedgid = getegid();
952 	if (saveduid == 0)
953 	{
954 		if (!DontInitGroups)
955 		{
956 			if (initgroups(uname, gid) == -1)
957 				syserr("include: initgroups(%s, %d) failed",
958 					uname, gid);
959 		}
960 		else
961 		{
962 			GIDSET_T gidset[1];
963 
964 			gidset[0] = gid;
965 			if (setgroups(1, gidset) == -1)
966 				syserr("include: setgroups() failed");
967 		}
968 
969 		if (gid != 0 && setgid(gid) < -1)
970 			syserr("setgid(%d) failure", gid);
971 		if (uid != 0)
972 		{
973 # if USESETEUID
974 			if (seteuid(uid) < 0)
975 				syserr("seteuid(%d) failure (real=%d, eff=%d)",
976 					uid, getuid(), geteuid());
977 # else
978 			if (setreuid(0, uid) < 0)
979 				syserr("setreuid(0, %d) failure (real=%d, eff=%d)",
980 					uid, getuid(), geteuid());
981 # endif
982 		}
983 	}
984 #endif
985 
986 	if (tTd(27, 9))
987 		printf("include: new uid = %d/%d\n",
988 		       (int) getuid(), (int) geteuid());
989 
990 	/*
991 	**  If home directory is remote mounted but server is down,
992 	**  this can hang or give errors; use a timeout to avoid this
993 	*/
994 
995 	if (setjmp(CtxIncludeTimeout) != 0)
996 	{
997 		ctladdr->q_flags |= QQUEUEUP;
998 		errno = 0;
999 
1000 		/* return pseudo-error code */
1001 		rval = E_SM_OPENTIMEOUT;
1002 		goto resetuid;
1003 	}
1004 	if (TimeOuts.to_fileopen > 0)
1005 		ev = setevent(TimeOuts.to_fileopen, includetimeout, 0);
1006 	else
1007 		ev = NULL;
1008 
1009 	/* check for writable parent directory */
1010 	p = strrchr(fname, '/');
1011 	if (p != NULL)
1012 	{
1013 		int ret;
1014 
1015 		*p = '\0';
1016 		ret = safedirpath(fname, uid, gid, uname, sfflags|SFF_SAFEDIRPATH);
1017 		if (ret == 0)
1018 		{
1019 			/* in safe directory: relax chown & link rules */
1020 			safedir = TRUE;
1021 			sfflags |= SFF_NOPATHCHECK;
1022 		}
1023 		else
1024 		{
1025 			if (bitset((forwarding ?
1026 				    DBS_FORWARDFILEINUNSAFEDIRPATH :
1027 				    DBS_INCLUDEFILEINUNSAFEDIRPATH),
1028 				   DontBlameSendmail))
1029 				sfflags |= SFF_NOPATHCHECK;
1030 			else if (bitset((forwarding ?
1031 					 DBS_FORWARDFILEINGROUPWRITABLEDIRPATH :
1032 					 DBS_INCLUDEFILEINGROUPWRITABLEDIRPATH),
1033 					DontBlameSendmail) &&
1034 				 ret == E_SM_GWDIR)
1035 			{
1036 				DontBlameSendmail |= DBS_GROUPWRITABLEDIRPATHSAFE;
1037 				ret = safedirpath(fname, uid,
1038 						  gid, uname,
1039 						  sfflags|SFF_SAFEDIRPATH);
1040 				DontBlameSendmail &= ~DBS_GROUPWRITABLEDIRPATHSAFE;
1041 				if (ret == 0)
1042 					sfflags |= SFF_NOPATHCHECK;
1043 				else
1044 					sfflags |= SFF_SAFEDIRPATH;
1045 			}
1046 			else
1047 				sfflags |= SFF_SAFEDIRPATH;
1048 			if (ret > E_PSEUDOBASE &&
1049 			    !bitset((forwarding ?
1050 				     DBS_FORWARDFILEINUNSAFEDIRPATHSAFE :
1051 				     DBS_INCLUDEFILEINUNSAFEDIRPATHSAFE),
1052 				    DontBlameSendmail))
1053 			{
1054 				if (LogLevel >= 12)
1055 					sm_syslog(LOG_INFO, e->e_id,
1056 						  "%s: unsafe directory path, marked unsafe",
1057 						  shortenstring(fname, MAXSHORTSTR));
1058 				ctladdr->q_flags |= QUNSAFEADDR;
1059 			}
1060 		}
1061 		*p = '/';
1062 	}
1063 
1064 	/* allow links only in unwritable directories */
1065 	if (!safedir &&
1066 	    !bitset((forwarding ?
1067 		     DBS_LINKEDFORWARDFILEINWRITABLEDIR :
1068 		     DBS_LINKEDINCLUDEFILEINWRITABLEDIR),
1069 		    DontBlameSendmail))
1070 		sfflags |= SFF_NOLINK;
1071 
1072 	rval = safefile(fname, uid, gid, uname, sfflags, S_IREAD, &st);
1073 	if (rval != 0)
1074 	{
1075 		/* don't use this :include: file */
1076 		if (tTd(27, 4))
1077 			printf("include: not safe (uid=%d): %s\n",
1078 				(int) uid, errstring(rval));
1079 	}
1080 	else if ((fp = fopen(fname, "r")) == NULL)
1081 	{
1082 		rval = errno;
1083 		if (tTd(27, 4))
1084 			printf("include: open: %s\n", errstring(rval));
1085 	}
1086 	else if (filechanged(fname, fileno(fp), &st))
1087 	{
1088 		rval = E_SM_FILECHANGE;
1089 		if (tTd(27, 4))
1090 			printf("include: file changed after open\n");
1091 	}
1092 	if (ev != NULL)
1093 		clrevent(ev);
1094 
1095 resetuid:
1096 
1097 #if HASSETREUID || USESETEUID
1098 	if (saveduid == 0)
1099 	{
1100 		if (uid != 0)
1101 		{
1102 # if USESETEUID
1103 			if (seteuid(0) < 0)
1104 				syserr("seteuid(0) failure (real=%d, eff=%d)",
1105 					getuid(), geteuid());
1106 # else
1107 			if (setreuid(-1, 0) < 0)
1108 				syserr("setreuid(-1, 0) failure (real=%d, eff=%d)",
1109 					getuid(), geteuid());
1110 			if (setreuid(RealUid, 0) < 0)
1111 				syserr("setreuid(%d, 0) failure (real=%d, eff=%d)",
1112 					RealUid, getuid(), geteuid());
1113 # endif
1114 		}
1115 		setgid(savedgid);
1116 	}
1117 #endif
1118 
1119 	if (tTd(27, 9))
1120 		printf("include: reset uid = %d/%d\n",
1121 		       (int) getuid(), (int) geteuid());
1122 
1123 	if (rval == E_SM_OPENTIMEOUT)
1124 		usrerr("451 open timeout on %s", fname);
1125 
1126 	if (fp == NULL)
1127 		return rval;
1128 
1129 	if (fstat(fileno(fp), &st) < 0)
1130 	{
1131 		rval = errno;
1132 		syserr("Cannot fstat %s!", fname);
1133 		return rval;
1134 	}
1135 
1136 	/* if path was writable, check to avoid file giveaway tricks */
1137 	safechown = chownsafe(fileno(fp), safedir);
1138 	if (tTd(27, 6))
1139 		printf("include: parent of %s is %s, chown is %ssafe\n",
1140 			fname,
1141 			safedir ? "safe" : "dangerous",
1142 			safechown ? "" : "un");
1143 
1144 	if (ca == NULL && safechown)
1145 	{
1146 		ctladdr->q_uid = st.st_uid;
1147 		ctladdr->q_gid = st.st_gid;
1148 		ctladdr->q_flags |= QGOODUID;
1149 	}
1150 	if (ca != NULL && ca->q_uid == st.st_uid)
1151 	{
1152 		/* optimization -- avoid getpwuid if we already have info */
1153 		ctladdr->q_flags |= ca->q_flags & QBOGUSSHELL;
1154 		ctladdr->q_ruser = ca->q_ruser;
1155 	}
1156 	else if (!forwarding)
1157 	{
1158 		register struct passwd *pw;
1159 
1160 		pw = sm_getpwuid(st.st_uid);
1161 		if (pw == NULL)
1162 			ctladdr->q_flags |= QBOGUSSHELL;
1163 		else
1164 		{
1165 			char *sh;
1166 
1167 			ctladdr->q_ruser = newstr(pw->pw_name);
1168 			if (safechown)
1169 				sh = pw->pw_shell;
1170 			else
1171 				sh = "/SENDMAIL/ANY/SHELL/";
1172 			if (!usershellok(pw->pw_name, sh))
1173 			{
1174 				if (LogLevel >= 12)
1175 					sm_syslog(LOG_INFO, e->e_id,
1176 						"%s: user %s has bad shell %s, marked %s",
1177 						shortenstring(fname, MAXSHORTSTR),
1178 						pw->pw_name, sh,
1179 						safechown ? "bogus" : "unsafe");
1180 				if (safechown)
1181 					ctladdr->q_flags |= QBOGUSSHELL;
1182 				else
1183 					ctladdr->q_flags |= QUNSAFEADDR;
1184 			}
1185 		}
1186 	}
1187 
1188 	if (bitset(EF_VRFYONLY, e->e_flags))
1189 	{
1190 		/* don't do any more now */
1191 		ctladdr->q_flags |= QVERIFIED;
1192 		e->e_nrcpts++;
1193 		xfclose(fp, "include", fname);
1194 		return rval;
1195 	}
1196 
1197 	/*
1198 	** Check to see if some bad guy can write this file
1199 	**
1200 	**	Group write checking could be more clever, e.g.,
1201 	**	guessing as to which groups are actually safe ("sys"
1202 	**	may be; "user" probably is not).
1203 	*/
1204 
1205 	mode = S_IWOTH;
1206 	if (!bitset((forwarding ?
1207 		     DBS_GROUPWRITABLEFORWARDFILESAFE :
1208 		     DBS_GROUPWRITABLEINCLUDEFILESAFE),
1209 		    DontBlameSendmail))
1210 		mode |= S_IWGRP;
1211 
1212 	if (bitset(mode, st.st_mode))
1213 	{
1214 		if (tTd(27, 6))
1215 			printf("include: %s is %s writable, marked unsafe\n",
1216 				shortenstring(fname, MAXSHORTSTR),
1217 				bitset(S_IWOTH, st.st_mode) ? "world" : "group");
1218 		if (LogLevel >= 12)
1219 			sm_syslog(LOG_INFO, e->e_id,
1220 				"%s: %s writable %s file, marked unsafe",
1221 				shortenstring(fname, MAXSHORTSTR),
1222 				bitset(S_IWOTH, st.st_mode) ? "world" : "group",
1223 				forwarding ? "forward" : ":include:");
1224 		ctladdr->q_flags |= QUNSAFEADDR;
1225 	}
1226 
1227 	/* read the file -- each line is a comma-separated list. */
1228 	FileName = fname;
1229 	LineNumber = 0;
1230 	ctladdr->q_flags &= ~QSELFREF;
1231 	nincludes = 0;
1232 	while (fgets(buf, sizeof buf, fp) != NULL)
1233 	{
1234 		register char *p = strchr(buf, '\n');
1235 
1236 		LineNumber++;
1237 		if (p != NULL)
1238 			*p = '\0';
1239 		if (buf[0] == '#' || buf[0] == '\0')
1240 			continue;
1241 
1242 		/* <sp>#@# introduces a comment anywhere */
1243 		/* for Japanese character sets */
1244 		for (p = buf; (p = strchr(++p, '#')) != NULL; )
1245 		{
1246 			if (p[1] == '@' && p[2] == '#' &&
1247 			    isascii(p[-1]) && isspace(p[-1]) &&
1248 			    (p[3] == '\0' || (isascii(p[3]) && isspace(p[3]))))
1249 			{
1250 				p[-1] = '\0';
1251 				break;
1252 			}
1253 		}
1254 		if (buf[0] == '\0')
1255 			continue;
1256 
1257 		e->e_to = NULL;
1258 		message("%s to %s",
1259 			forwarding ? "forwarding" : "sending", buf);
1260 		if (forwarding && LogLevel > 9)
1261 			sm_syslog(LOG_INFO, e->e_id,
1262 				"forward %.200s => %s",
1263 				oldto, shortenstring(buf, MAXSHORTSTR));
1264 
1265 		nincludes += sendtolist(buf, ctladdr, sendq, aliaslevel + 1, e);
1266 	}
1267 
1268 	if (ferror(fp) && tTd(27, 3))
1269 		printf("include: read error: %s\n", errstring(errno));
1270 	if (nincludes > 0 && !bitset(QSELFREF, ctladdr->q_flags))
1271 	{
1272 		if (tTd(27, 5))
1273 		{
1274 			printf("include: QDONTSEND ");
1275 			printaddr(ctladdr, FALSE);
1276 		}
1277 		ctladdr->q_flags |= QDONTSEND;
1278 	}
1279 
1280 	(void) xfclose(fp, "include", fname);
1281 	FileName = oldfilename;
1282 	LineNumber = oldlinenumber;
1283 	e->e_to = oldto;
1284 	return rval;
1285 }
1286 
1287 static void
1288 includetimeout()
1289 {
1290 	longjmp(CtxIncludeTimeout, 1);
1291 }
1292 /*
1293 **  SENDTOARGV -- send to an argument vector.
1294 **
1295 **	Parameters:
1296 **		argv -- argument vector to send to.
1297 **		e -- the current envelope.
1298 **
1299 **	Returns:
1300 **		none.
1301 **
1302 **	Side Effects:
1303 **		puts all addresses on the argument vector onto the
1304 **			send queue.
1305 */
1306 
1307 void
1308 sendtoargv(argv, e)
1309 	register char **argv;
1310 	register ENVELOPE *e;
1311 {
1312 	register char *p;
1313 
1314 	while ((p = *argv++) != NULL)
1315 	{
1316 		(void) sendtolist(p, NULLADDR, &e->e_sendqueue, 0, e);
1317 	}
1318 }
1319 /*
1320 **  GETCTLADDR -- get controlling address from an address header.
1321 **
1322 **	If none, get one corresponding to the effective userid.
1323 **
1324 **	Parameters:
1325 **		a -- the address to find the controller of.
1326 **
1327 **	Returns:
1328 **		the controlling address.
1329 **
1330 **	Side Effects:
1331 **		none.
1332 */
1333 
1334 ADDRESS *
1335 getctladdr(a)
1336 	register ADDRESS *a;
1337 {
1338 	while (a != NULL && !bitset(QGOODUID, a->q_flags))
1339 		a = a->q_alias;
1340 	return (a);
1341 }
1342 /*
1343 **  SELF_REFERENCE -- check to see if an address references itself
1344 **
1345 **	The check is done through a chain of aliases.  If it is part of
1346 **	a loop, break the loop at the "best" address, that is, the one
1347 **	that exists as a real user.
1348 **
1349 **	This is to handle the case of:
1350 **		awc:		Andrew.Chang
1351 **		Andrew.Chang:	awc@mail.server
1352 **	which is a problem only on mail.server.
1353 **
1354 **	Parameters:
1355 **		a -- the address to check.
1356 **		e -- the current envelope.
1357 **
1358 **	Returns:
1359 **		The address that should be retained.
1360 */
1361 
1362 ADDRESS *
1363 self_reference(a, e)
1364 	ADDRESS *a;
1365 	ENVELOPE *e;
1366 {
1367 	ADDRESS *b;		/* top entry in self ref loop */
1368 	ADDRESS *c;		/* entry that point to a real mail box */
1369 
1370 	if (tTd(27, 1))
1371 		printf("self_reference(%s)\n", a->q_paddr);
1372 
1373 	for (b = a->q_alias; b != NULL; b = b->q_alias)
1374 	{
1375 		if (sameaddr(a, b))
1376 			break;
1377 	}
1378 
1379 	if (b == NULL)
1380 	{
1381 		if (tTd(27, 1))
1382 			printf("\t... no self ref\n");
1383 		return NULL;
1384 	}
1385 
1386 	/*
1387 	**  Pick the first address that resolved to a real mail box
1388 	**  i.e has a pw entry.  The returned value will be marked
1389 	**  QSELFREF in recipient(), which in turn will disable alias()
1390 	**  from marking it QDONTSEND, which mean it will be used
1391 	**  as a deliverable address.
1392 	**
1393 	**  The 2 key thing to note here are:
1394 	**	1) we are in a recursive call sequence:
1395 	**		alias->sentolist->recipient->alias
1396 	**	2) normally, when we return back to alias(), the address
1397 	**	   will be marked QDONTSEND, since alias() assumes the
1398 	**	   expanded form will be used instead of the current address.
1399 	**	   This behaviour is turned off if the address is marked
1400 	**	   QSELFREF We set QSELFREF when we return to recipient().
1401 	*/
1402 
1403 	c = a;
1404 	while (c != NULL)
1405 	{
1406 		if (bitnset(M_HASPWENT, c->q_mailer->m_flags))
1407 		{
1408 			if (tTd(27, 2))
1409 				printf("\t... getpwnam(%s)... ", c->q_user);
1410 			if (sm_getpwnam(c->q_user) != NULL)
1411 			{
1412 				if (tTd(27, 2))
1413 					printf("found\n");
1414 
1415 				/* ought to cache results here */
1416 				if (sameaddr(b, c))
1417 					return b;
1418 				else
1419 					return c;
1420 			}
1421 			if (tTd(27, 2))
1422 				printf("failed\n");
1423 		}
1424 		c = c->q_alias;
1425 	}
1426 
1427 	if (tTd(27, 1))
1428 		printf("\t... cannot break loop for \"%s\"\n", a->q_paddr);
1429 
1430 	return NULL;
1431 }
1432