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