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