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