source: trunk/third/sendmail/sendmail/recipient.c @ 19204

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