source: trunk/third/sendmail/sendmail/deliver.c @ 22421

Revision 22421, 140.6 KB checked in by zacheiss, 19 years ago (diff)
Apply patches from 3-22-06 CERT advisory.
Line 
1/*
2 * Copyright (c) 1998-2003 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#include <sys/time.h>
16
17SM_RCSID("@(#)$Id: deliver.c,v 1.3 2006-03-23 21:02:45 zacheiss Exp $")
18
19#if HASSETUSERCONTEXT
20# include <login_cap.h>
21#endif /* HASSETUSERCONTEXT */
22
23#if NETINET || NETINET6
24# include <arpa/inet.h>
25#endif /* NETINET || NETINET6 */
26
27#if STARTTLS || SASL
28# include "sfsasl.h"
29#endif /* STARTTLS || SASL */
30
31void            markfailure __P((ENVELOPE *, ADDRESS *, MCI *, int, bool));
32static int      deliver __P((ENVELOPE *, ADDRESS *));
33static void     dup_queue_file __P((ENVELOPE *, ENVELOPE *, int));
34static void     mailfiletimeout __P((void));
35static int      parse_hostsignature __P((char *, char **, MAILER *));
36static void     sendenvelope __P((ENVELOPE *, int));
37extern MCI      *mci_new __P((SM_RPOOL_T *));
38static int      coloncmp __P((const char *, const char *));
39
40#if STARTTLS
41static int      starttls __P((MAILER *, MCI *, ENVELOPE *));
42static int      endtlsclt __P((MCI *));
43#endif /* STARTTLS */
44# if STARTTLS || SASL
45static bool     iscltflgset __P((ENVELOPE *, int));
46# endif /* STARTTLS || SASL */
47
48extern char *porttouse;
49
50/*
51**  SENDALL -- actually send all the messages.
52**
53**      Parameters:
54**              e -- the envelope to send.
55**              mode -- the delivery mode to use.  If SM_DEFAULT, use
56**                      the current e->e_sendmode.
57**
58**      Returns:
59**              none.
60**
61**      Side Effects:
62**              Scans the send lists and sends everything it finds.
63**              Delivers any appropriate error messages.
64**              If we are running in a non-interactive mode, takes the
65**                      appropriate action.
66*/
67
68void
69sendall(e, mode)
70        ENVELOPE *e;
71        int mode;
72{
73        register ADDRESS *q;
74        char *owner;
75        int otherowners;
76        int save_errno;
77        register ENVELOPE *ee;
78        ENVELOPE *splitenv = NULL;
79        int oldverbose = Verbose;
80        bool somedeliveries = false, expensive = false;
81        pid_t pid;
82
83        /*
84        **  If this message is to be discarded, don't bother sending
85        **  the message at all.
86        */
87
88        if (bitset(EF_DISCARD, e->e_flags))
89        {
90                if (tTd(13, 1))
91                        sm_dprintf("sendall: discarding id %s\n", e->e_id);
92                e->e_flags |= EF_CLRQUEUE;
93                if (LogLevel > 9)
94                        logundelrcpts(e, "discarded", 9, true);
95                else if (LogLevel > 4)
96                        sm_syslog(LOG_INFO, e->e_id, "discarded");
97                markstats(e, NULL, STATS_REJECT);
98                return;
99        }
100
101        /*
102        **  If we have had global, fatal errors, don't bother sending
103        **  the message at all if we are in SMTP mode.  Local errors
104        **  (e.g., a single address failing) will still cause the other
105        **  addresses to be sent.
106        */
107
108        if (bitset(EF_FATALERRS, e->e_flags) &&
109            (OpMode == MD_SMTP || OpMode == MD_DAEMON))
110        {
111                e->e_flags |= EF_CLRQUEUE;
112                return;
113        }
114
115        /* determine actual delivery mode */
116        if (mode == SM_DEFAULT)
117        {
118                mode = e->e_sendmode;
119                if (mode != SM_VERIFY && mode != SM_DEFER &&
120                    shouldqueue(e->e_msgpriority, e->e_ctime))
121                        mode = SM_QUEUE;
122        }
123
124        if (tTd(13, 1))
125        {
126                sm_dprintf("\n===== SENDALL: mode %c, id %s, e_from ",
127                        mode, e->e_id);
128                printaddr(&e->e_from, false);
129                sm_dprintf("\te_flags = ");
130                printenvflags(e);
131                sm_dprintf("sendqueue:\n");
132                printaddr(e->e_sendqueue, true);
133        }
134
135        /*
136        **  Do any preprocessing necessary for the mode we are running.
137        **      Check to make sure the hop count is reasonable.
138        **      Delete sends to the sender in mailing lists.
139        */
140
141        CurEnv = e;
142        if (tTd(62, 1))
143                checkfds(NULL);
144
145        if (e->e_hopcount > MaxHopCount)
146        {
147                char *recip;
148
149                if (e->e_sendqueue != NULL &&
150                    e->e_sendqueue->q_paddr != NULL)
151                        recip = e->e_sendqueue->q_paddr;
152                else
153                        recip = "(nobody)";
154
155                errno = 0;
156                queueup(e, WILL_BE_QUEUED(mode), false);
157                e->e_flags |= EF_FATALERRS|EF_PM_NOTIFY|EF_CLRQUEUE;
158                ExitStat = EX_UNAVAILABLE;
159                syserr("554 5.4.6 Too many hops %d (%d max): from %s via %s, to %s",
160                       e->e_hopcount, MaxHopCount, e->e_from.q_paddr,
161                       RealHostName == NULL ? "localhost" : RealHostName,
162                       recip);
163                for (q = e->e_sendqueue; q != NULL; q = q->q_next)
164                {
165                        if (QS_IS_DEAD(q->q_state))
166                                continue;
167                        q->q_state = QS_BADADDR;
168                        q->q_status = "5.4.6";
169                        q->q_rstatus = "554 5.4.6 Too many hops";
170                }
171                return;
172        }
173
174        /*
175        **  Do sender deletion.
176        **
177        **      If the sender should be queued up, skip this.
178        **      This can happen if the name server is hosed when you
179        **      are trying to send mail.  The result is that the sender
180        **      is instantiated in the queue as a recipient.
181        */
182
183        if (!bitset(EF_METOO, e->e_flags) &&
184            !QS_IS_QUEUEUP(e->e_from.q_state))
185        {
186                if (tTd(13, 5))
187                {
188                        sm_dprintf("sendall: QS_SENDER ");
189                        printaddr(&e->e_from, false);
190                }
191                e->e_from.q_state = QS_SENDER;
192                (void) recipient(&e->e_from, &e->e_sendqueue, 0, e);
193        }
194
195        /*
196        **  Handle alias owners.
197        **
198        **      We scan up the q_alias chain looking for owners.
199        **      We discard owners that are the same as the return path.
200        */
201
202        for (q = e->e_sendqueue; q != NULL; q = q->q_next)
203        {
204                register struct address *a;
205
206                for (a = q; a != NULL && a->q_owner == NULL; a = a->q_alias)
207                        continue;
208                if (a != NULL)
209                        q->q_owner = a->q_owner;
210
211                if (q->q_owner != NULL &&
212                    !QS_IS_DEAD(q->q_state) &&
213                    strcmp(q->q_owner, e->e_from.q_paddr) == 0)
214                        q->q_owner = NULL;
215        }
216
217        if (tTd(13, 25))
218        {
219                sm_dprintf("\nAfter first owner pass, sendq =\n");
220                printaddr(e->e_sendqueue, true);
221        }
222
223        owner = "";
224        otherowners = 1;
225        while (owner != NULL && otherowners > 0)
226        {
227                if (tTd(13, 28))
228                        sm_dprintf("owner = \"%s\", otherowners = %d\n",
229                                   owner, otherowners);
230                owner = NULL;
231                otherowners = bitset(EF_SENDRECEIPT, e->e_flags) ? 1 : 0;
232
233                for (q = e->e_sendqueue; q != NULL; q = q->q_next)
234                {
235                        if (tTd(13, 30))
236                        {
237                                sm_dprintf("Checking ");
238                                printaddr(q, false);
239                        }
240                        if (QS_IS_DEAD(q->q_state))
241                        {
242                                if (tTd(13, 30))
243                                        sm_dprintf("    ... QS_IS_DEAD\n");
244                                continue;
245                        }
246                        if (tTd(13, 29) && !tTd(13, 30))
247                        {
248                                sm_dprintf("Checking ");
249                                printaddr(q, false);
250                        }
251
252                        if (q->q_owner != NULL)
253                        {
254                                if (owner == NULL)
255                                {
256                                        if (tTd(13, 40))
257                                                sm_dprintf("    ... First owner = \"%s\"\n",
258                                                           q->q_owner);
259                                        owner = q->q_owner;
260                                }
261                                else if (owner != q->q_owner)
262                                {
263                                        if (strcmp(owner, q->q_owner) == 0)
264                                        {
265                                                if (tTd(13, 40))
266                                                        sm_dprintf("    ... Same owner = \"%s\"\n",
267                                                                   owner);
268
269                                                /* make future comparisons cheap */
270                                                q->q_owner = owner;
271                                        }
272                                        else
273                                        {
274                                                if (tTd(13, 40))
275                                                        sm_dprintf("    ... Another owner \"%s\"\n",
276                                                                   q->q_owner);
277                                                otherowners++;
278                                        }
279                                        owner = q->q_owner;
280                                }
281                                else if (tTd(13, 40))
282                                        sm_dprintf("    ... Same owner = \"%s\"\n",
283                                                   owner);
284                        }
285                        else
286                        {
287                                if (tTd(13, 40))
288                                        sm_dprintf("    ... Null owner\n");
289                                otherowners++;
290                        }
291
292                        if (QS_IS_BADADDR(q->q_state))
293                        {
294                                if (tTd(13, 30))
295                                        sm_dprintf("    ... QS_IS_BADADDR\n");
296                                continue;
297                        }
298
299                        if (QS_IS_QUEUEUP(q->q_state))
300                        {
301                                MAILER *m = q->q_mailer;
302
303                                /*
304                                **  If we have temporary address failures
305                                **  (e.g., dns failure) and a fallback MX is
306                                **  set, send directly to the fallback MX host.
307                                */
308
309                                if (FallBackMX != NULL &&
310                                    !wordinclass(FallBackMX, 'w') &&
311                                    mode != SM_VERIFY &&
312                                    !bitnset(M_NOMX, m->m_flags) &&
313                                    strcmp(m->m_mailer, "[IPC]") == 0 &&
314                                    m->m_argv[0] != NULL &&
315                                    strcmp(m->m_argv[0], "TCP") == 0)
316                                {
317                                        int len;
318                                        char *p;
319
320                                        if (tTd(13, 30))
321                                                sm_dprintf("    ... FallBackMX\n");
322
323                                        len = strlen(FallBackMX) + 1;
324                                        p = sm_rpool_malloc_x(e->e_rpool, len);
325                                        (void) sm_strlcpy(p, FallBackMX, len);
326                                        q->q_state = QS_OK;
327                                        q->q_host = p;
328                                }
329                                else
330                                {
331                                        if (tTd(13, 30))
332                                                sm_dprintf("    ... QS_IS_QUEUEUP\n");
333                                        continue;
334                                }
335                        }
336
337                        /*
338                        **  If this mailer is expensive, and if we don't
339                        **  want to make connections now, just mark these
340                        **  addresses and return.  This is useful if we
341                        **  want to batch connections to reduce load.  This
342                        **  will cause the messages to be queued up, and a
343                        **  daemon will come along to send the messages later.
344                        */
345
346                        if (NoConnect && !Verbose &&
347                            bitnset(M_EXPENSIVE, q->q_mailer->m_flags))
348                        {
349                                if (tTd(13, 30))
350                                        sm_dprintf("    ... expensive\n");
351                                q->q_state = QS_QUEUEUP;
352                                expensive = true;
353                        }
354                        else if (bitnset(M_HOLD, q->q_mailer->m_flags) &&
355                                 QueueLimitId == NULL &&
356                                 QueueLimitSender == NULL &&
357                                 QueueLimitRecipient == NULL)
358                        {
359                                if (tTd(13, 30))
360                                        sm_dprintf("    ... hold\n");
361                                q->q_state = QS_QUEUEUP;
362                                expensive = true;
363                        }
364#if _FFR_QUARANTINE
365                        else if (QueueMode != QM_QUARANTINE &&
366                                 e->e_quarmsg != NULL)
367                        {
368                                if (tTd(13, 30))
369                                        sm_dprintf("    ... quarantine: %s\n",
370                                                   e->e_quarmsg);
371                                q->q_state = QS_QUEUEUP;
372                                expensive = true;
373                        }
374#endif /* _FFR_QUARANTINE */
375                        else
376                        {
377                                if (tTd(13, 30))
378                                        sm_dprintf("    ... deliverable\n");
379                                somedeliveries = true;
380                        }
381                }
382
383                if (owner != NULL && otherowners > 0)
384                {
385                        /*
386                        **  Split this envelope into two.
387                        */
388
389                        ee = (ENVELOPE *) sm_rpool_malloc_x(e->e_rpool,
390                                                            sizeof *ee);
391                        STRUCTCOPY(*e, *ee);
392                        ee->e_message = NULL;
393                        ee->e_id = NULL;
394                        assign_queueid(ee);
395
396                        if (tTd(13, 1))
397                                sm_dprintf("sendall: split %s into %s, owner = \"%s\", otherowners = %d\n",
398                                           e->e_id, ee->e_id, owner,
399                                           otherowners);
400
401                        ee->e_header = copyheader(e->e_header, ee->e_rpool);
402                        ee->e_sendqueue = copyqueue(e->e_sendqueue,
403                                                    ee->e_rpool);
404                        ee->e_errorqueue = copyqueue(e->e_errorqueue,
405                                                     ee->e_rpool);
406                        ee->e_flags = e->e_flags & ~(EF_INQUEUE|EF_CLRQUEUE|EF_FATALERRS|EF_SENDRECEIPT|EF_RET_PARAM);
407                        ee->e_flags |= EF_NORECEIPT;
408                        setsender(owner, ee, NULL, '\0', true);
409                        if (tTd(13, 5))
410                        {
411                                sm_dprintf("sendall(split): QS_SENDER ");
412                                printaddr(&ee->e_from, false);
413                        }
414                        ee->e_from.q_state = QS_SENDER;
415                        ee->e_dfp = NULL;
416                        ee->e_lockfp = NULL;
417                        ee->e_xfp = NULL;
418                        ee->e_qgrp = e->e_qgrp;
419                        ee->e_qdir = e->e_qdir;
420                        ee->e_errormode = EM_MAIL;
421                        ee->e_sibling = splitenv;
422                        ee->e_statmsg = NULL;
423#if _FFR_QUARANTINE
424                        if (e->e_quarmsg != NULL)
425                                ee->e_quarmsg = sm_rpool_strdup_x(ee->e_rpool,
426                                                                  e->e_quarmsg);
427#endif /* _FFR_QUARANTINE */
428                        splitenv = ee;
429
430                        for (q = e->e_sendqueue; q != NULL; q = q->q_next)
431                        {
432                                if (q->q_owner == owner)
433                                {
434                                        q->q_state = QS_CLONED;
435                                        if (tTd(13, 6))
436                                                sm_dprintf("\t... stripping %s from original envelope\n",
437                                                           q->q_paddr);
438                                }
439                        }
440                        for (q = ee->e_sendqueue; q != NULL; q = q->q_next)
441                        {
442                                if (q->q_owner != owner)
443                                {
444                                        q->q_state = QS_CLONED;
445                                        if (tTd(13, 6))
446                                                sm_dprintf("\t... dropping %s from cloned envelope\n",
447                                                           q->q_paddr);
448                                }
449                                else
450                                {
451                                        /* clear DSN parameters */
452                                        q->q_flags &= ~(QHASNOTIFY|Q_PINGFLAGS);
453                                        q->q_flags |= DefaultNotify & ~QPINGONSUCCESS;
454                                        if (tTd(13, 6))
455                                                sm_dprintf("\t... moving %s to cloned envelope\n",
456                                                           q->q_paddr);
457                                }
458                        }
459
460                        if (mode != SM_VERIFY && bitset(EF_HAS_DF, e->e_flags))
461                                dup_queue_file(e, ee, DATAFL_LETTER);
462
463                        /*
464                        **  Give the split envelope access to the parent
465                        **  transcript file for errors obtained while
466                        **  processing the recipients (done before the
467                        **  envelope splitting).
468                        */
469
470                        if (e->e_xfp != NULL)
471                                ee->e_xfp = sm_io_dup(e->e_xfp);
472
473                        /* failed to dup e->e_xfp, start a new transcript */
474                        if (ee->e_xfp == NULL)
475                                openxscript(ee);
476
477                        if (mode != SM_VERIFY && LogLevel > 4)
478                                sm_syslog(LOG_INFO, e->e_id,
479                                          "%s: clone: owner=%s",
480                                          ee->e_id, owner);
481                }
482        }
483
484        if (owner != NULL)
485        {
486                setsender(owner, e, NULL, '\0', true);
487                if (tTd(13, 5))
488                {
489                        sm_dprintf("sendall(owner): QS_SENDER ");
490                        printaddr(&e->e_from, false);
491                }
492                e->e_from.q_state = QS_SENDER;
493                e->e_errormode = EM_MAIL;
494                e->e_flags |= EF_NORECEIPT;
495                e->e_flags &= ~EF_FATALERRS;
496        }
497
498        /* if nothing to be delivered, just queue up everything */
499        if (!somedeliveries && !WILL_BE_QUEUED(mode) &&
500            mode != SM_VERIFY)
501        {
502                time_t now;
503
504                if (tTd(13, 29))
505                        sm_dprintf("No deliveries: auto-queuing\n");
506                mode = SM_QUEUE;
507                now = curtime();
508
509                /* treat this as a delivery in terms of counting tries */
510                e->e_dtime = now;
511                if (!expensive)
512                        e->e_ntries++;
513                for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
514                {
515                        ee->e_dtime = now;
516                        if (!expensive)
517                                ee->e_ntries++;
518                }
519        }
520
521        if ((WILL_BE_QUEUED(mode) || mode == SM_FORK ||
522             (mode != SM_VERIFY && SuperSafe == SAFE_REALLY)) &&
523            (!bitset(EF_INQUEUE, e->e_flags) || splitenv != NULL))
524        {
525                bool msync;
526
527                /*
528                **  Be sure everything is instantiated in the queue.
529                **  Split envelopes first in case the machine crashes.
530                **  If the original were done first, we may lose
531                **  recipients.
532                */
533
534#if !HASFLOCK
535                msync = false;
536#else /* !HASFLOCK */
537                msync = mode == SM_FORK;
538#endif /* !HASFLOCK */
539
540                for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
541                        queueup(ee, WILL_BE_QUEUED(mode), msync);
542                queueup(e, WILL_BE_QUEUED(mode), msync);
543        }
544
545        if (tTd(62, 10))
546                checkfds("after envelope splitting");
547
548        /*
549        **  If we belong in background, fork now.
550        */
551
552        if (tTd(13, 20))
553        {
554                sm_dprintf("sendall: final mode = %c\n", mode);
555                if (tTd(13, 21))
556                {
557                        sm_dprintf("\n================ Final Send Queue(s) =====================\n");
558                        sm_dprintf("\n  *** Envelope %s, e_from=%s ***\n",
559                                   e->e_id, e->e_from.q_paddr);
560                        printaddr(e->e_sendqueue, true);
561                        for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
562                        {
563                                sm_dprintf("\n  *** Envelope %s, e_from=%s ***\n",
564                                           ee->e_id, ee->e_from.q_paddr);
565                                printaddr(ee->e_sendqueue, true);
566                        }
567                        sm_dprintf("==========================================================\n\n");
568                }
569        }
570        switch (mode)
571        {
572          case SM_VERIFY:
573                Verbose = 2;
574                break;
575
576          case SM_QUEUE:
577          case SM_DEFER:
578#if HASFLOCK
579  queueonly:
580#endif /* HASFLOCK */
581                if (e->e_nrcpts > 0)
582                        e->e_flags |= EF_INQUEUE;
583                dropenvelope(e, splitenv != NULL, true);
584                for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
585                {
586                        if (ee->e_nrcpts > 0)
587                                ee->e_flags |= EF_INQUEUE;
588                        dropenvelope(ee, false, true);
589                }
590                return;
591
592          case SM_FORK:
593                if (e->e_xfp != NULL)
594                        (void) sm_io_flush(e->e_xfp, SM_TIME_DEFAULT);
595
596#if !HASFLOCK
597                /*
598                **  Since fcntl locking has the interesting semantic that
599                **  the lock is owned by a process, not by an open file
600                **  descriptor, we have to flush this to the queue, and
601                **  then restart from scratch in the child.
602                */
603
604                {
605                        /* save id for future use */
606                        char *qid = e->e_id;
607
608                        /* now drop the envelope in the parent */
609                        e->e_flags |= EF_INQUEUE;
610                        dropenvelope(e, splitenv != NULL, false);
611
612                        /* arrange to reacquire lock after fork */
613                        e->e_id = qid;
614                }
615
616                for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
617                {
618                        /* save id for future use */
619                        char *qid = ee->e_id;
620
621                        /* drop envelope in parent */
622                        ee->e_flags |= EF_INQUEUE;
623                        dropenvelope(ee, false, false);
624
625                        /* and save qid for reacquisition */
626                        ee->e_id = qid;
627                }
628#endif /* !HASFLOCK */
629
630                /*
631                **  Since the delivery may happen in a child and the parent
632                **  does not wait, the parent may close the maps thereby
633                **  removing any shared memory used by the map.  Therefore,
634                **  close the maps now so the child will dynamically open
635                **  them if necessary.
636                */
637
638                closemaps(false);
639
640                pid = fork();
641                if (pid < 0)
642                {
643                        syserr("deliver: fork 1");
644#if HASFLOCK
645                        goto queueonly;
646#else /* HASFLOCK */
647                        e->e_id = NULL;
648                        for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
649                                ee->e_id = NULL;
650                        return;
651#endif /* HASFLOCK */
652                }
653                else if (pid > 0)
654                {
655#if HASFLOCK
656                        /* be sure we leave the temp files to our child */
657                        /* close any random open files in the envelope */
658                        closexscript(e);
659                        if (e->e_dfp != NULL)
660                                (void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT);
661                        e->e_dfp = NULL;
662                        e->e_flags &= ~EF_HAS_DF;
663
664                        /* can't call unlockqueue to avoid unlink of xfp */
665                        if (e->e_lockfp != NULL)
666                                (void) sm_io_close(e->e_lockfp, SM_TIME_DEFAULT);
667                        else
668                                syserr("%s: sendall: null lockfp", e->e_id);
669                        e->e_lockfp = NULL;
670#endif /* HASFLOCK */
671
672                        /* make sure the parent doesn't own the envelope */
673                        e->e_id = NULL;
674
675#if USE_DOUBLE_FORK
676                        /* catch intermediate zombie */
677                        (void) waitfor(pid);
678#endif /* USE_DOUBLE_FORK */
679                        return;
680                }
681
682                /* Reset global flags */
683                RestartRequest = NULL;
684                RestartWorkGroup = false;
685                ShutdownRequest = NULL;
686                PendingSignal = 0;
687
688                /*
689                **  Initialize exception stack and default exception
690                **  handler for child process.
691                */
692
693                sm_exc_newthread(fatal_error);
694
695                /*
696                **  Since we have accepted responsbility for the message,
697                **  change the SIGTERM handler.  intsig() (the old handler)
698                **  would remove the envelope if this was a command line
699                **  message submission.
700                */
701
702                (void) sm_signal(SIGTERM, SIG_DFL);
703
704#if USE_DOUBLE_FORK
705                /* double fork to avoid zombies */
706                pid = fork();
707                if (pid > 0)
708                        exit(EX_OK);
709                save_errno = errno;
710#endif /* USE_DOUBLE_FORK */
711
712                CurrentPid = getpid();
713
714                /* be sure we are immune from the terminal */
715                disconnect(2, e);
716                clearstats();
717
718                /* prevent parent from waiting if there was an error */
719                if (pid < 0)
720                {
721                        errno = save_errno;
722                        syserr("deliver: fork 2");
723#if HASFLOCK
724                        e->e_flags |= EF_INQUEUE;
725#else /* HASFLOCK */
726                        e->e_id = NULL;
727#endif /* HASFLOCK */
728                        finis(true, true, ExitStat);
729                }
730
731                /* be sure to give error messages in child */
732                QuickAbort = false;
733
734                /*
735                **  Close any cached connections.
736                **
737                **      We don't send the QUIT protocol because the parent
738                **      still knows about the connection.
739                **
740                **      This should only happen when delivering an error
741                **      message.
742                */
743
744                mci_flush(false, NULL);
745
746#if HASFLOCK
747                break;
748#else /* HASFLOCK */
749
750                /*
751                **  Now reacquire and run the various queue files.
752                */
753
754                for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
755                {
756                        ENVELOPE *sibling = ee->e_sibling;
757
758                        (void) dowork(ee->e_qgrp, ee->e_qdir, ee->e_id,
759                                      false, false, ee);
760                        ee->e_sibling = sibling;
761                }
762                (void) dowork(e->e_qgrp, e->e_qdir, e->e_id,
763                              false, false, e);
764                finis(true, true, ExitStat);
765#endif /* HASFLOCK */
766        }
767
768        sendenvelope(e, mode);
769        dropenvelope(e, true, true);
770        for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
771        {
772                CurEnv = ee;
773                if (mode != SM_VERIFY)
774                        openxscript(ee);
775                sendenvelope(ee, mode);
776                dropenvelope(ee, true, true);
777        }
778        CurEnv = e;
779
780        Verbose = oldverbose;
781        if (mode == SM_FORK)
782                finis(true, true, ExitStat);
783}
784
785static void
786sendenvelope(e, mode)
787        register ENVELOPE *e;
788        int mode;
789{
790        register ADDRESS *q;
791        bool didany;
792
793        if (tTd(13, 10))
794                sm_dprintf("sendenvelope(%s) e_flags=0x%lx\n",
795                           e->e_id == NULL ? "[NOQUEUE]" : e->e_id,
796                           e->e_flags);
797        if (LogLevel > 80)
798                sm_syslog(LOG_DEBUG, e->e_id,
799                          "sendenvelope, flags=0x%lx",
800                          e->e_flags);
801
802        /*
803        **  If we have had global, fatal errors, don't bother sending
804        **  the message at all if we are in SMTP mode.  Local errors
805        **  (e.g., a single address failing) will still cause the other
806        **  addresses to be sent.
807        */
808
809        if (bitset(EF_FATALERRS, e->e_flags) &&
810            (OpMode == MD_SMTP || OpMode == MD_DAEMON))
811        {
812                e->e_flags |= EF_CLRQUEUE;
813                return;
814        }
815
816        /*
817        **  Don't attempt deliveries if we want to bounce now
818        **  or if deliver-by time is exceeded.
819        */
820
821        if (!bitset(EF_RESPONSE, e->e_flags) &&
822            (TimeOuts.to_q_return[e->e_timeoutclass] == NOW ||
823             (IS_DLVR_RETURN(e) && e->e_deliver_by > 0 &&
824              curtime() > e->e_ctime + e->e_deliver_by)))
825                return;
826
827        /*
828        **  Run through the list and send everything.
829        **
830        **      Set EF_GLOBALERRS so that error messages during delivery
831        **      result in returned mail.
832        */
833
834        e->e_nsent = 0;
835        e->e_flags |= EF_GLOBALERRS;
836
837        macdefine(&e->e_macro, A_PERM, macid("{envid}"), e->e_envid);
838        macdefine(&e->e_macro, A_PERM, macid("{bodytype}"), e->e_bodytype);
839        didany = false;
840
841        if (!bitset(EF_SPLIT, e->e_flags))
842        {
843                ENVELOPE *oldsib;
844                ENVELOPE *ee;
845
846                /*
847                **  Save old sibling and set it to NULL to avoid
848                **  queueing up the same envelopes again.
849                **  This requires that envelopes in that list have
850                **  been take care of before (or at some other place).
851                */
852
853                oldsib = e->e_sibling;
854                e->e_sibling = NULL;
855                if (!split_by_recipient(e) &&
856                    bitset(EF_FATALERRS, e->e_flags))
857                {
858                        if (OpMode == MD_SMTP || OpMode == MD_DAEMON)
859                                e->e_flags |= EF_CLRQUEUE;
860                        return;
861                }
862                for (ee = e->e_sibling; ee != NULL; ee = ee->e_sibling)
863                        queueup(ee, false, true);
864
865                /* clean up */
866                for (ee = e->e_sibling; ee != NULL; ee = ee->e_sibling)
867                {
868                        /* now unlock the job */
869                        closexscript(ee);
870                        unlockqueue(ee);
871
872                        /* this envelope is marked unused */
873                        if (ee->e_dfp != NULL)
874                        {
875                                (void) sm_io_close(ee->e_dfp, SM_TIME_DEFAULT);
876                                ee->e_dfp = NULL;
877                        }
878                        ee->e_id = NULL;
879                        ee->e_flags &= ~EF_HAS_DF;
880                }
881                e->e_sibling = oldsib;
882        }
883
884        /* now run through the queue */
885        for (q = e->e_sendqueue; q != NULL; q = q->q_next)
886        {
887#if XDEBUG
888                char wbuf[MAXNAME + 20];
889
890                (void) sm_snprintf(wbuf, sizeof wbuf, "sendall(%.*s)",
891                                   MAXNAME, q->q_paddr);
892                checkfd012(wbuf);
893#endif /* XDEBUG */
894                if (mode == SM_VERIFY)
895                {
896                        e->e_to = q->q_paddr;
897                        if (QS_IS_SENDABLE(q->q_state))
898                        {
899                                if (q->q_host != NULL && q->q_host[0] != '\0')
900                                        message("deliverable: mailer %s, host %s, user %s",
901                                                q->q_mailer->m_name,
902                                                q->q_host,
903                                                q->q_user);
904                                else
905                                        message("deliverable: mailer %s, user %s",
906                                                q->q_mailer->m_name,
907                                                q->q_user);
908                        }
909                }
910                else if (QS_IS_OK(q->q_state))
911                {
912                        /*
913                        **  Checkpoint the send list every few addresses
914                        */
915
916                        if (CheckpointInterval > 0 &&
917                            e->e_nsent >= CheckpointInterval)
918                        {
919                                queueup(e, false, false);
920                                e->e_nsent = 0;
921                        }
922                        (void) deliver(e, q);
923                        didany = true;
924                }
925        }
926        if (didany)
927        {
928                e->e_dtime = curtime();
929                e->e_ntries++;
930        }
931
932#if XDEBUG
933        checkfd012("end of sendenvelope");
934#endif /* XDEBUG */
935}
936
937#if REQUIRES_DIR_FSYNC
938/*
939**  SYNC_DIR -- fsync a directory based on a filename
940**
941**      Parameters:
942**              filename -- path of file
943**              panic -- panic?
944**
945**      Returns:
946**              none
947*/
948
949void
950sync_dir(filename, panic)
951        char *filename;
952        bool panic;
953{
954        int dirfd;
955        char *dirp;
956        char dir[MAXPATHLEN];
957
958#if _FFR_REQ_DIR_FSYNC_OPT
959        if (!RequiresDirfsync)
960                return;
961#endif /* _FFR_REQ_DIR_FSYNC_OPT */
962
963        /* filesystems which require the directory be synced */
964        dirp = strrchr(filename, '/');
965        if (dirp != NULL)
966        {
967                if (sm_strlcpy(dir, filename, sizeof dir) >= sizeof dir)
968                        return;
969                dir[dirp - filename] = '\0';
970                dirp = dir;
971        }
972        else
973                dirp = ".";
974        dirfd = open(dirp, O_RDONLY, 0700);
975        if (tTd(40,32))
976                sm_syslog(LOG_INFO, NOQID, "sync_dir: %s: fsync(%d)",
977                          dirp, dirfd);
978        if (dirfd >= 0)
979        {
980                if (fsync(dirfd) < 0)
981                {
982                        if (panic)
983                                syserr("!sync_dir: cannot fsync directory %s",
984                                       dirp);
985                        else if (LogLevel > 1)
986                                sm_syslog(LOG_ERR, NOQID,
987                                          "sync_dir: cannot fsync directory %s: %s",
988                                          dirp, sm_errstring(errno));
989                }
990                (void) close(dirfd);
991        }
992}
993#endif /* REQUIRES_DIR_FSYNC */
994/*
995**  DUP_QUEUE_FILE -- duplicate a queue file into a split queue
996**
997**      Parameters:
998**              e -- the existing envelope
999**              ee -- the new envelope
1000**              type -- the queue file type (e.g., DATAFL_LETTER)
1001**
1002**      Returns:
1003**              none
1004*/
1005
1006static void
1007dup_queue_file(e, ee, type)
1008        ENVELOPE *e, *ee;
1009        int type;
1010{
1011        char f1buf[MAXPATHLEN], f2buf[MAXPATHLEN];
1012
1013        ee->e_dfp = NULL;
1014        ee->e_xfp = NULL;
1015
1016        /*
1017        **  Make sure both are in the same directory.
1018        */
1019
1020        (void) sm_strlcpy(f1buf, queuename(e, type), sizeof f1buf);
1021        (void) sm_strlcpy(f2buf, queuename(ee, type), sizeof f2buf);
1022
1023        /* Force the df to disk if it's not there yet */
1024        if (type == DATAFL_LETTER && e->e_dfp != NULL &&
1025            sm_io_setinfo(e->e_dfp, SM_BF_COMMIT, NULL) < 0 &&
1026            errno != EINVAL)
1027        {
1028                syserr("!dup_queue_file: can't commit %s", f1buf);
1029                /* NOTREACHED */
1030        }
1031
1032        if (link(f1buf, f2buf) < 0)
1033        {
1034                int save_errno = errno;
1035
1036                syserr("sendall: link(%s, %s)", f1buf, f2buf);
1037                if (save_errno == EEXIST)
1038                {
1039                        if (unlink(f2buf) < 0)
1040                        {
1041                                syserr("!sendall: unlink(%s): permanent",
1042                                       f2buf);
1043                                /* NOTREACHED */
1044                        }
1045                        if (link(f1buf, f2buf) < 0)
1046                        {
1047                                syserr("!sendall: link(%s, %s): permanent",
1048                                       f1buf, f2buf);
1049                                /* NOTREACHED */
1050                        }
1051                }
1052        }
1053        SYNC_DIR(f2buf, true);
1054}
1055/*
1056**  DOFORK -- do a fork, retrying a couple of times on failure.
1057**
1058**      This MUST be a macro, since after a vfork we are running
1059**      two processes on the same stack!!!
1060**
1061**      Parameters:
1062**              none.
1063**
1064**      Returns:
1065**              From a macro???  You've got to be kidding!
1066**
1067**      Side Effects:
1068**              Modifies the ==> LOCAL <== variable 'pid', leaving:
1069**                      pid of child in parent, zero in child.
1070**                      -1 on unrecoverable error.
1071**
1072**      Notes:
1073**              I'm awfully sorry this looks so awful.  That's
1074**              vfork for you.....
1075*/
1076
1077#define NFORKTRIES      5
1078
1079#ifndef FORK
1080# define FORK   fork
1081#endif /* ! FORK */
1082
1083#define DOFORK(fORKfN) \
1084{\
1085        register int i;\
1086\
1087        for (i = NFORKTRIES; --i >= 0; )\
1088        {\
1089                pid = fORKfN();\
1090                if (pid >= 0)\
1091                        break;\
1092                if (i > 0)\
1093                        (void) sleep((unsigned) NFORKTRIES - i);\
1094        }\
1095}
1096/*
1097**  DOFORK -- simple fork interface to DOFORK.
1098**
1099**      Parameters:
1100**              none.
1101**
1102**      Returns:
1103**              pid of child in parent.
1104**              zero in child.
1105**              -1 on error.
1106**
1107**      Side Effects:
1108**              returns twice, once in parent and once in child.
1109*/
1110
1111pid_t
1112dofork()
1113{
1114        register pid_t pid = -1;
1115
1116        DOFORK(fork);
1117        return pid;
1118}
1119
1120/*
1121**  COLONCMP -- compare host-signatures up to first ':' or EOS
1122**
1123**      This takes two strings which happen to be host-signatures and
1124**      compares them. If the lowest preference portions of the MX-RR's
1125**      match (up to ':' or EOS, whichever is first), then we have
1126**      match. This is used for coattail-piggybacking messages during
1127**      message delivery.
1128**      If the signatures are the same up to the first ':' the remainder of
1129**      the signatures are then compared with a normal strcmp(). This saves
1130**      re-examining the first part of the signatures.
1131**
1132**      Parameters:
1133**              a - first host-signature
1134**              b - second host-signature
1135**
1136**      Returns:
1137**              HS_MATCH_NO -- no "match".
1138**              HS_MATCH_FIRST -- "match" for the first MX preference
1139**                      (up to the first colon (':')).
1140**              HS_MATCH_FULL -- match for the entire MX record.
1141**
1142**      Side Effects:
1143**              none.
1144*/
1145
1146#define HS_MATCH_NO     0
1147#define HS_MATCH_FIRST  1
1148#define HS_MATCH_FULL   2
1149
1150static int
1151coloncmp(a, b)
1152        register const char *a;
1153        register const char *b;
1154{
1155        int ret = HS_MATCH_NO;
1156        int braclev = 0;
1157
1158        while (*a == *b++)
1159        {
1160                /* Need to account for IPv6 bracketed addresses */
1161                if (*a == '[')
1162                        braclev++;
1163                else if (*a == ']' && braclev > 0)
1164                        braclev--;
1165                else if (*a == ':' && braclev <= 0)
1166                {
1167                        ret = HS_MATCH_FIRST;
1168                        a++;
1169                        break;
1170                }
1171                else if (*a == '\0')
1172                        return HS_MATCH_FULL; /* a full match */
1173                a++;
1174        }
1175        if (ret == HS_MATCH_NO &&
1176            braclev <= 0 &&
1177            ((*a == '\0' && *(b - 1) == ':') ||
1178             (*a == ':' && *(b - 1) == '\0')))
1179                return HS_MATCH_FIRST;
1180        if (ret == HS_MATCH_FIRST && strcmp(a, b) == 0)
1181                return HS_MATCH_FULL;
1182
1183        return ret;
1184}
1185/*
1186**  DELIVER -- Deliver a message to a list of addresses.
1187**
1188**      This routine delivers to everyone on the same host as the
1189**      user on the head of the list.  It is clever about mailers
1190**      that don't handle multiple users.  It is NOT guaranteed
1191**      that it will deliver to all these addresses however -- so
1192**      deliver should be called once for each address on the
1193**      list.
1194**      Deliver tries to be as opportunistic as possible about piggybacking
1195**      messages. Some definitions to make understanding easier follow below.
1196**      Piggybacking occurs when an existing connection to a mail host can
1197**      be used to send the same message to more than one recipient at the
1198**      same time. So "no piggybacking" means one message for one recipient
1199**      per connection. "Intentional piggybacking" happens when the
1200**      recipients' host address (not the mail host address) is used to
1201**      attempt piggybacking. Recipients with the same host address
1202**      have the same mail host. "Coincidental piggybacking" relies on
1203**      piggybacking based on all the mail host addresses in the MX-RR. This
1204**      is "coincidental" in the fact it could not be predicted until the
1205**      MX Resource Records for the hosts were obtained and examined. For
1206**      example (preference order and equivalence is important, not values):
1207**              domain1 IN MX 10 mxhost-A
1208**                      IN MX 20 mxhost-B
1209**              domain2 IN MX  4 mxhost-A
1210**                      IN MX  8 mxhost-B
1211**      Domain1 and domain2 can piggyback the same message to mxhost-A or
1212**      mxhost-B (if mxhost-A cannot be reached).
1213**      "Coattail piggybacking" relaxes the strictness of "coincidental
1214**      piggybacking" in the hope that most significant (lowest value)
1215**      MX preference host(s) can create more piggybacking. For example
1216**      (again, preference order and equivalence is important, not values):
1217**              domain3 IN MX 100 mxhost-C
1218**                      IN MX 100 mxhost-D
1219**                      IN MX 200 mxhost-E
1220**              domain4 IN MX  50 mxhost-C
1221**                      IN MX  50 mxhost-D
1222**                      IN MX  80 mxhost-F
1223**      A message for domain3 and domain4 can piggyback to mxhost-C if mxhost-C
1224**      is available. Same with mxhost-D because in both RR's the preference
1225**      value is the same as mxhost-C, respectively.
1226**      So deliver attempts coattail piggybacking when possible. If the
1227**      first MX preference level hosts cannot be used then the piggybacking
1228**      reverts to coincidental piggybacking. Using the above example you
1229**      cannot deliver to mxhost-F for domain3 regardless of preference value.
1230**      ("Coattail" from "riding on the coattails of your predecessor" meaning
1231**      gaining benefit from a predecessor effort with no or little addition
1232**      effort. The predecessor here being the preceding MX RR).
1233**
1234**      Parameters:
1235**              e -- the envelope to deliver.
1236**              firstto -- head of the address list to deliver to.
1237**
1238**      Returns:
1239**              zero -- successfully delivered.
1240**              else -- some failure, see ExitStat for more info.
1241**
1242**      Side Effects:
1243**              The standard input is passed off to someone.
1244*/
1245
1246#ifndef NO_UID
1247# define NO_UID         -1
1248#endif /* ! NO_UID */
1249#ifndef NO_GID
1250# define NO_GID         -1
1251#endif /* ! NO_GID */
1252
1253static int
1254deliver(e, firstto)
1255        register ENVELOPE *e;
1256        ADDRESS *firstto;
1257{
1258        char *host;                     /* host being sent to */
1259        char *user;                     /* user being sent to */
1260        char **pvp;
1261        register char **mvp;
1262        register char *p;
1263        register MAILER *m;             /* mailer for this recipient */
1264        ADDRESS *volatile ctladdr;
1265#if HASSETUSERCONTEXT
1266        ADDRESS *volatile contextaddr = NULL;
1267#endif /* HASSETUSERCONTEXT */
1268        register MCI *volatile mci;
1269        register ADDRESS *SM_NONVOLATILE to = firstto;
1270        volatile bool clever = false;   /* running user smtp to this mailer */
1271        ADDRESS *volatile tochain = NULL; /* users chain in this mailer call */
1272        int rcode;                      /* response code */
1273        SM_NONVOLATILE int lmtp_rcode = EX_OK;
1274        SM_NONVOLATILE int nummxhosts = 0; /* number of MX hosts available */
1275        SM_NONVOLATILE int hostnum = 0; /* current MX host index */
1276        char *firstsig;                 /* signature of firstto */
1277        volatile pid_t pid = -1;
1278        char *volatile curhost;
1279        SM_NONVOLATILE unsigned short port = 0;
1280        SM_NONVOLATILE time_t enough = 0;
1281#if NETUNIX
1282        char *SM_NONVOLATILE mux_path = NULL;   /* path to UNIX domain socket */
1283#endif /* NETUNIX */
1284        time_t xstart;
1285        bool suidwarn;
1286        bool anyok;                     /* at least one address was OK */
1287        SM_NONVOLATILE bool goodmxfound = false; /* at least one MX was OK */
1288        bool ovr;
1289#if _FFR_QUARANTINE
1290        bool quarantine;
1291#endif /* _FFR_QUARANTINE */
1292        int strsize;
1293        int rcptcount;
1294        int ret;
1295        static int tobufsize = 0;
1296        static char *tobuf = NULL;
1297        char *rpath;    /* translated return path */
1298        int mpvect[2];
1299        int rpvect[2];
1300        char *mxhosts[MAXMXHOSTS + 1];
1301        char *pv[MAXPV + 1];
1302        char buf[MAXNAME + 1];
1303        char cbuf[MAXPATHLEN];
1304
1305        errno = 0;
1306        if (!QS_IS_OK(to->q_state))
1307                return 0;
1308
1309        suidwarn = geteuid() == 0;
1310
1311        m = to->q_mailer;
1312        host = to->q_host;
1313        CurEnv = e;                     /* just in case */
1314        e->e_statmsg = NULL;
1315        SmtpError[0] = '\0';
1316        xstart = curtime();
1317
1318        if (tTd(10, 1))
1319                sm_dprintf("\n--deliver, id=%s, mailer=%s, host=`%s', first user=`%s'\n",
1320                        e->e_id, m->m_name, host, to->q_user);
1321        if (tTd(10, 100))
1322                printopenfds(false);
1323
1324        /*
1325        **  Clear {client_*} macros if this is a bounce message to
1326        **  prevent rejection by check_compat ruleset.
1327        */
1328
1329        if (bitset(EF_RESPONSE, e->e_flags))
1330        {
1331                macdefine(&e->e_macro, A_PERM, macid("{client_name}"), "");
1332                macdefine(&e->e_macro, A_PERM, macid("{client_addr}"), "");
1333                macdefine(&e->e_macro, A_PERM, macid("{client_port}"), "");
1334                macdefine(&e->e_macro, A_PERM, macid("{client_resolve}"), "");
1335        }
1336
1337        SM_TRY
1338        {
1339        ADDRESS *skip_back = NULL;
1340
1341        /*
1342        **  Do initial argv setup.
1343        **      Insert the mailer name.  Notice that $x expansion is
1344        **      NOT done on the mailer name.  Then, if the mailer has
1345        **      a picky -f flag, we insert it as appropriate.  This
1346        **      code does not check for 'pv' overflow; this places a
1347        **      manifest lower limit of 4 for MAXPV.
1348        **              The from address rewrite is expected to make
1349        **              the address relative to the other end.
1350        */
1351
1352        /* rewrite from address, using rewriting rules */
1353        rcode = EX_OK;
1354        if (bitnset(M_UDBENVELOPE, e->e_from.q_mailer->m_flags))
1355                p = e->e_sender;
1356        else
1357                p = e->e_from.q_paddr;
1358        rpath = remotename(p, m, RF_SENDERADDR|RF_CANONICAL, &rcode, e);
1359        if (strlen(rpath) > MAXSHORTSTR)
1360        {
1361                rpath = shortenstring(rpath, MAXSHORTSTR);
1362
1363                /* avoid bogus errno */
1364                errno = 0;
1365                syserr("remotename: huge return path %s", rpath);
1366        }
1367        rpath = sm_rpool_strdup_x(e->e_rpool, rpath);
1368        macdefine(&e->e_macro, A_PERM, 'g', rpath);
1369        macdefine(&e->e_macro, A_PERM, 'h', host);
1370        Errors = 0;
1371        pvp = pv;
1372        *pvp++ = m->m_argv[0];
1373
1374        /* insert -f or -r flag as appropriate */
1375        if (FromFlag &&
1376            (bitnset(M_FOPT, m->m_flags) ||
1377             bitnset(M_ROPT, m->m_flags)))
1378        {
1379                if (bitnset(M_FOPT, m->m_flags))
1380                        *pvp++ = "-f";
1381                else
1382                        *pvp++ = "-r";
1383                *pvp++ = rpath;
1384        }
1385
1386        /*
1387        **  Append the other fixed parts of the argv.  These run
1388        **  up to the first entry containing "$u".  There can only
1389        **  be one of these, and there are only a few more slots
1390        **  in the pv after it.
1391        */
1392
1393        for (mvp = m->m_argv; (p = *++mvp) != NULL; )
1394        {
1395                /* can't use strchr here because of sign extension problems */
1396                while (*p != '\0')
1397                {
1398                        if ((*p++ & 0377) == MACROEXPAND)
1399                        {
1400                                if (*p == 'u')
1401                                        break;
1402                        }
1403                }
1404
1405                if (*p != '\0')
1406                        break;
1407
1408                /* this entry is safe -- go ahead and process it */
1409                expand(*mvp, buf, sizeof buf, e);
1410                *pvp++ = sm_rpool_strdup_x(e->e_rpool, buf);
1411                if (pvp >= &pv[MAXPV - 3])
1412                {
1413                        syserr("554 5.3.5 Too many parameters to %s before $u",
1414                               pv[0]);
1415                        rcode = -1;
1416                        goto cleanup;
1417                }
1418        }
1419
1420        /*
1421        **  If we have no substitution for the user name in the argument
1422        **  list, we know that we must supply the names otherwise -- and
1423        **  SMTP is the answer!!
1424        */
1425
1426        if (*mvp == NULL)
1427        {
1428                /* running LMTP or SMTP */
1429                clever = true;
1430                *pvp = NULL;
1431        }
1432        else if (bitnset(M_LMTP, m->m_flags))
1433        {
1434                /* not running LMTP */
1435                sm_syslog(LOG_ERR, NULL,
1436                          "Warning: mailer %s: LMTP flag (F=z) turned off",
1437                          m->m_name);
1438                clrbitn(M_LMTP, m->m_flags);
1439        }
1440
1441        /*
1442        **  At this point *mvp points to the argument with $u.  We
1443        **  run through our address list and append all the addresses
1444        **  we can.  If we run out of space, do not fret!  We can
1445        **  always send another copy later.
1446        */
1447
1448        e->e_to = NULL;
1449        strsize = 2;
1450        rcptcount = 0;
1451        ctladdr = NULL;
1452        if (firstto->q_signature == NULL)
1453                firstto->q_signature = hostsignature(firstto->q_mailer,
1454                                                     firstto->q_host);
1455        firstsig = firstto->q_signature;
1456
1457        for (; to != NULL; to = to->q_next)
1458        {
1459                /* avoid sending multiple recipients to dumb mailers */
1460                if (tochain != NULL && !bitnset(M_MUSER, m->m_flags))
1461                        break;
1462
1463                /* if already sent or not for this host, don't send */
1464                if (!QS_IS_OK(to->q_state)) /* already sent; look at next */
1465                        continue;
1466
1467                /*
1468                **  Must be same mailer to keep grouping rcpts.
1469                **  If mailers don't match: continue; sendqueue is not
1470                **  sorted by mailers, so don't break;
1471                */
1472
1473                if (to->q_mailer != firstto->q_mailer)
1474                        continue;
1475
1476                if (to->q_signature == NULL) /* for safety */
1477                        to->q_signature = hostsignature(to->q_mailer,
1478                                                        to->q_host);
1479
1480                /*
1481                **  This is for coincidental and tailcoat piggybacking messages
1482                **  to the same mail host. While the signatures are identical
1483                **  (that's the MX-RR's are identical) we can do coincidental
1484                **  piggybacking. We try hard for coattail piggybacking
1485                **  with the same mail host when the next recipient has the
1486                **  same host at lowest preference. It may be that this
1487                **  won't work out, so 'skip_back' is maintained if a backup
1488                **  to coincidental piggybacking or full signature must happen.
1489                */
1490
1491                ret = firstto == to ? HS_MATCH_FULL :
1492                                      coloncmp(to->q_signature, firstsig);
1493                if (ret == HS_MATCH_FULL)
1494                        skip_back = to;
1495                else if (ret == HS_MATCH_NO)
1496                        break;
1497
1498                if (!clever)
1499                {
1500                        /* avoid overflowing tobuf */
1501                        strsize += strlen(to->q_paddr) + 1;
1502                        if (strsize > TOBUFSIZE)
1503                                break;
1504                }
1505
1506                if (++rcptcount > to->q_mailer->m_maxrcpt)
1507                        break;
1508
1509                if (tTd(10, 1))
1510                {
1511                        sm_dprintf("\nsend to ");
1512                        printaddr(to, false);
1513                }
1514
1515                /* compute effective uid/gid when sending */
1516                if (bitnset(M_RUNASRCPT, to->q_mailer->m_flags))
1517# if HASSETUSERCONTEXT
1518                        contextaddr = ctladdr = getctladdr(to);
1519# else /* HASSETUSERCONTEXT */
1520                        ctladdr = getctladdr(to);
1521# endif /* HASSETUSERCONTEXT */
1522
1523                if (tTd(10, 2))
1524                {
1525                        sm_dprintf("ctladdr=");
1526                        printaddr(ctladdr, false);
1527                }
1528
1529                user = to->q_user;
1530                e->e_to = to->q_paddr;
1531
1532                /*
1533                **  Check to see that these people are allowed to
1534                **  talk to each other.
1535                **  Check also for overflow of e_msgsize.
1536                */
1537
1538                if (m->m_maxsize != 0 &&
1539                    (e->e_msgsize > m->m_maxsize || e->e_msgsize < 0))
1540                {
1541                        e->e_flags |= EF_NO_BODY_RETN;
1542                        if (bitnset(M_LOCALMAILER, to->q_mailer->m_flags))
1543                                to->q_status = "5.2.3";
1544                        else
1545                                to->q_status = "5.3.4";
1546
1547                        /* set to->q_rstatus = NULL; or to the following? */
1548                        usrerrenh(to->q_status,
1549                                  "552 Message is too large; %ld bytes max",
1550                                  m->m_maxsize);
1551                        markfailure(e, to, NULL, EX_UNAVAILABLE, false);
1552                        giveresponse(EX_UNAVAILABLE, to->q_status, m,
1553                                     NULL, ctladdr, xstart, e, to);
1554                        continue;
1555                }
1556                SM_SET_H_ERRNO(0);
1557                ovr = true;
1558
1559                /* do config file checking of compatibility */
1560#if _FFR_QUARANTINE
1561                quarantine = (e->e_quarmsg != NULL);
1562#endif /* _FFR_QUARANTINE */
1563                rcode = rscheck("check_compat", e->e_from.q_paddr, to->q_paddr,
1564                                e, RSF_RMCOMM|RSF_COUNT, 3, NULL,
1565                                e->e_id);
1566                if (rcode == EX_OK)
1567                {
1568                        /* do in-code checking if not discarding */
1569                        if (!bitset(EF_DISCARD, e->e_flags))
1570                        {
1571                                rcode = checkcompat(to, e);
1572                                ovr = false;
1573                        }
1574                }
1575                if (rcode != EX_OK)
1576                {
1577                        markfailure(e, to, NULL, rcode, ovr);
1578                        giveresponse(rcode, to->q_status, m,
1579                                     NULL, ctladdr, xstart, e, to);
1580                        continue;
1581                }
1582#if _FFR_QUARANTINE
1583                if (!quarantine && e->e_quarmsg != NULL)
1584                {
1585                        /*
1586                        **  check_compat or checkcompat() has tried
1587                        **  to quarantine but that isn't supported.
1588                        **  Revert the attempt.
1589                        */
1590
1591                        e->e_quarmsg = NULL;
1592                        macdefine(&e->e_macro, A_PERM,
1593                                  macid("{quarantine}"), "");
1594                }
1595#endif /* _FFR_QUARANTINE */
1596                if (bitset(EF_DISCARD, e->e_flags))
1597                {
1598                        if (tTd(10, 5))
1599                        {
1600                                sm_dprintf("deliver: discarding recipient ");
1601                                printaddr(to, false);
1602                        }
1603
1604                        /* pretend the message was sent */
1605                        /* XXX should we log something here? */
1606                        to->q_state = QS_DISCARDED;
1607
1608                        /*
1609                        **  Remove discard bit to prevent discard of
1610                        **  future recipients.  This is safe because the
1611                        **  true "global discard" has been handled before
1612                        **  we get here.
1613                        */
1614
1615                        e->e_flags &= ~EF_DISCARD;
1616                        continue;
1617                }
1618
1619                /*
1620                **  Strip quote bits from names if the mailer is dumb
1621                **      about them.
1622                */
1623
1624                if (bitnset(M_STRIPQ, m->m_flags))
1625                {
1626                        stripquotes(user);
1627                        stripquotes(host);
1628                }
1629#if _FFR_STRIPBACKSL
1630                /*
1631                **  Strip one leading backslash if requested and the
1632                **  next character is alphanumerical (the latter can
1633                **  probably relaxed a bit, see RFC2821).
1634                */
1635
1636                if (bitnset(M_STRIPBACKSL, m->m_flags) && user[0] == '\\')
1637                        stripbackslash(user);
1638#endif /* _FFR_STRIPBACKSL */
1639
1640                /* hack attack -- delivermail compatibility */
1641                if (m == ProgMailer && *user == '|')
1642                        user++;
1643
1644                /*
1645                **  If an error message has already been given, don't
1646                **      bother to send to this address.
1647                **
1648                **      >>>>>>>>>> This clause assumes that the local mailer
1649                **      >> NOTE >> cannot do any further aliasing; that
1650                **      >>>>>>>>>> function is subsumed by sendmail.
1651                */
1652
1653                if (!QS_IS_OK(to->q_state))
1654                        continue;
1655
1656                /*
1657                **  See if this user name is "special".
1658                **      If the user name has a slash in it, assume that this
1659                **      is a file -- send it off without further ado.  Note
1660                **      that this type of addresses is not processed along
1661                **      with the others, so we fudge on the To person.
1662                */
1663
1664                if (strcmp(m->m_mailer, "[FILE]") == 0)
1665                {
1666                        macdefine(&e->e_macro, A_PERM, 'u', user);
1667                        p = to->q_home;
1668                        if (p == NULL && ctladdr != NULL)
1669                                p = ctladdr->q_home;
1670                        macdefine(&e->e_macro, A_PERM, 'z', p);
1671                        expand(m->m_argv[1], buf, sizeof buf, e);
1672                        if (strlen(buf) > 0)
1673                                rcode = mailfile(buf, m, ctladdr, SFF_CREAT, e);
1674                        else
1675                        {
1676                                syserr("empty filename specification for mailer %s",
1677                                       m->m_name);
1678                                rcode = EX_CONFIG;
1679                        }
1680                        giveresponse(rcode, to->q_status, m, NULL,
1681                                     ctladdr, xstart, e, to);
1682                        markfailure(e, to, NULL, rcode, true);
1683                        e->e_nsent++;
1684                        if (rcode == EX_OK)
1685                        {
1686                                to->q_state = QS_SENT;
1687                                if (bitnset(M_LOCALMAILER, m->m_flags) &&
1688                                    bitset(QPINGONSUCCESS, to->q_flags))
1689                                {
1690                                        to->q_flags |= QDELIVERED;
1691                                        to->q_status = "2.1.5";
1692                                        (void) sm_io_fprintf(e->e_xfp,
1693                                                             SM_TIME_DEFAULT,
1694                                                             "%s... Successfully delivered\n",
1695                                                             to->q_paddr);
1696                                }
1697                        }
1698                        to->q_statdate = curtime();
1699                        markstats(e, to, STATS_NORMAL);
1700                        continue;
1701                }
1702
1703                /*
1704                **  Address is verified -- add this user to mailer
1705                **  argv, and add it to the print list of recipients.
1706                */
1707
1708                /* link together the chain of recipients */
1709                to->q_tchain = tochain;
1710                tochain = to;
1711                e->e_to = "[CHAIN]";
1712
1713                macdefine(&e->e_macro, A_PERM, 'u', user);  /* to user */
1714                p = to->q_home;
1715                if (p == NULL && ctladdr != NULL)
1716                        p = ctladdr->q_home;
1717                macdefine(&e->e_macro, A_PERM, 'z', p);  /* user's home */
1718
1719                /* set the ${dsn_notify} macro if applicable */
1720                if (bitset(QHASNOTIFY, to->q_flags))
1721                {
1722                        char notify[MAXLINE];
1723
1724                        notify[0] = '\0';
1725                        if (bitset(QPINGONSUCCESS, to->q_flags))
1726                                (void) sm_strlcat(notify, "SUCCESS,",
1727                                                  sizeof notify);
1728                        if (bitset(QPINGONFAILURE, to->q_flags))
1729                                (void) sm_strlcat(notify, "FAILURE,",
1730                                                  sizeof notify);
1731                        if (bitset(QPINGONDELAY, to->q_flags))
1732                                (void) sm_strlcat(notify, "DELAY,",
1733                                                  sizeof notify);
1734
1735                        /* Set to NEVER or drop trailing comma */
1736                        if (notify[0] == '\0')
1737                                (void) sm_strlcat(notify, "NEVER",
1738                                                  sizeof notify);
1739                        else
1740                                notify[strlen(notify) - 1] = '\0';
1741
1742                        macdefine(&e->e_macro, A_TEMP,
1743                                macid("{dsn_notify}"), notify);
1744                }
1745                else
1746                        macdefine(&e->e_macro, A_PERM,
1747                                macid("{dsn_notify}"), NULL);
1748
1749                /*
1750                **  Expand out this user into argument list.
1751                */
1752
1753                if (!clever)
1754                {
1755                        expand(*mvp, buf, sizeof buf, e);
1756                        *pvp++ = sm_rpool_strdup_x(e->e_rpool, buf);
1757                        if (pvp >= &pv[MAXPV - 2])
1758                        {
1759                                /* allow some space for trailing parms */
1760                                break;
1761                        }
1762                }
1763        }
1764
1765        /* see if any addresses still exist */
1766        if (tochain == NULL)
1767        {
1768                rcode = 0;
1769                goto cleanup;
1770        }
1771
1772        /* print out messages as full list */
1773        strsize = 1;
1774        for (to = tochain; to != NULL; to = to->q_tchain)
1775                strsize += strlen(to->q_paddr) + 1;
1776        if (strsize < TOBUFSIZE)
1777                strsize = TOBUFSIZE;
1778        if (strsize > tobufsize)
1779        {
1780                SM_FREE_CLR(tobuf);
1781                tobuf = sm_pmalloc_x(strsize);
1782                tobufsize = strsize;
1783        }
1784        p = tobuf;
1785        *p = '\0';
1786        for (to = tochain; to != NULL; to = to->q_tchain)
1787        {
1788                (void) sm_strlcpyn(p, tobufsize - (p - tobuf), 2,
1789                                   ",", to->q_paddr);
1790                p += strlen(p);
1791        }
1792        e->e_to = tobuf + 1;
1793
1794        /*
1795        **  Fill out any parameters after the $u parameter.
1796        */
1797
1798        if (!clever)
1799        {
1800                while (*++mvp != NULL)
1801                {
1802                        expand(*mvp, buf, sizeof buf, e);
1803                        *pvp++ = sm_rpool_strdup_x(e->e_rpool, buf);
1804                        if (pvp >= &pv[MAXPV])
1805                                syserr("554 5.3.0 deliver: pv overflow after $u for %s",
1806                                       pv[0]);
1807                }
1808        }
1809        *pvp++ = NULL;
1810
1811        /*
1812        **  Call the mailer.
1813        **      The argument vector gets built, pipes
1814        **      are created as necessary, and we fork & exec as
1815        **      appropriate.
1816        **      If we are running SMTP, we just need to clean up.
1817        */
1818
1819        /* XXX this seems a bit wierd */
1820        if (ctladdr == NULL && m != ProgMailer && m != FileMailer &&
1821            bitset(QGOODUID, e->e_from.q_flags))
1822                ctladdr = &e->e_from;
1823
1824#if NAMED_BIND
1825        if (ConfigLevel < 2)
1826                _res.options &= ~(RES_DEFNAMES | RES_DNSRCH);   /* XXX */
1827#endif /* NAMED_BIND */
1828
1829        if (tTd(11, 1))
1830        {
1831                sm_dprintf("openmailer:");
1832                printav(pv);
1833        }
1834        errno = 0;
1835        SM_SET_H_ERRNO(0);
1836        CurHostName = NULL;
1837
1838        /*
1839        **  Deal with the special case of mail handled through an IPC
1840        **  connection.
1841        **      In this case we don't actually fork.  We must be
1842        **      running SMTP for this to work.  We will return a
1843        **      zero pid to indicate that we are running IPC.
1844        **  We also handle a debug version that just talks to stdin/out.
1845        */
1846
1847        curhost = NULL;
1848        SmtpPhase = NULL;
1849        mci = NULL;
1850
1851#if XDEBUG
1852        {
1853                char wbuf[MAXLINE];
1854
1855                /* make absolutely certain 0, 1, and 2 are in use */
1856                (void) sm_snprintf(wbuf, sizeof wbuf, "%s... openmailer(%s)",
1857                                   shortenstring(e->e_to, MAXSHORTSTR),
1858                                   m->m_name);
1859                checkfd012(wbuf);
1860        }
1861#endif /* XDEBUG */
1862
1863        /* check for 8-bit available */
1864        if (bitset(EF_HAS8BIT, e->e_flags) &&
1865            bitnset(M_7BITS, m->m_flags) &&
1866            (bitset(EF_DONT_MIME, e->e_flags) ||
1867             !(bitset(MM_MIME8BIT, MimeMode) ||
1868               (bitset(EF_IS_MIME, e->e_flags) &&
1869                bitset(MM_CVTMIME, MimeMode)))))
1870        {
1871                e->e_status = "5.6.3";
1872                usrerrenh(e->e_status,
1873                          "554 Cannot send 8-bit data to 7-bit destination");
1874                rcode = EX_DATAERR;
1875                goto give_up;
1876        }
1877
1878        if (tTd(62, 8))
1879                checkfds("before delivery");
1880
1881        /* check for Local Person Communication -- not for mortals!!! */
1882        if (strcmp(m->m_mailer, "[LPC]") == 0)
1883        {
1884#if _FFR_CACHE_LPC
1885                if (clever)
1886                {
1887                        /* flush any expired connections */
1888                        (void) mci_scan(NULL);
1889
1890                        /* try to get a cached connection or just a slot */
1891                        mci = mci_get(m->m_name, m);
1892                        if (mci->mci_host == NULL)
1893                                mci->mci_host = m->m_name;
1894                        CurHostName = mci->mci_host;
1895                        if (mci->mci_state != MCIS_CLOSED)
1896                        {
1897                                message("Using cached SMTP/LPC connection for %s...",
1898                                        m->m_name);
1899                                mci->mci_deliveries++;
1900                                goto do_transfer;
1901                        }
1902                }
1903                else
1904                {
1905                        mci = mci_new(e->e_rpool);
1906                }
1907                mci->mci_in = smioin;
1908                mci->mci_out = smioout;
1909                mci->mci_mailer = m;
1910                mci->mci_host = m->m_name;
1911                if (clever)
1912                {
1913                        mci->mci_state = MCIS_OPENING;
1914                        mci_cache(mci);
1915                }
1916                else
1917                        mci->mci_state = MCIS_OPEN;
1918#else /* _FFR_CACHE_LPC */
1919                mci = mci_new(e->e_rpool);
1920                mci->mci_in = smioin;
1921                mci->mci_out = smioout;
1922                mci->mci_state = clever ? MCIS_OPENING : MCIS_OPEN;
1923                mci->mci_mailer = m;
1924#endif /* _FFR_CACHE_LPC */
1925        }
1926        else if (strcmp(m->m_mailer, "[IPC]") == 0)
1927        {
1928                register int i;
1929
1930                if (pv[0] == NULL || pv[1] == NULL || pv[1][0] == '\0')
1931                {
1932                        syserr("null destination for %s mailer", m->m_mailer);
1933                        rcode = EX_CONFIG;
1934                        goto give_up;
1935                }
1936
1937# if NETUNIX
1938                if (strcmp(pv[0], "FILE") == 0)
1939                {
1940                        curhost = CurHostName = "localhost";
1941                        mux_path = pv[1];
1942                }
1943                else
1944# endif /* NETUNIX */
1945                {
1946                        CurHostName = pv[1];
1947                        curhost = hostsignature(m, pv[1]);
1948                }
1949
1950                if (curhost == NULL || curhost[0] == '\0')
1951                {
1952                        syserr("null host signature for %s", pv[1]);
1953                        rcode = EX_CONFIG;
1954                        goto give_up;
1955                }
1956
1957                if (!clever)
1958                {
1959                        syserr("554 5.3.5 non-clever IPC");
1960                        rcode = EX_CONFIG;
1961                        goto give_up;
1962                }
1963                if (pv[2] != NULL || porttouse != NULL
1964# if NETUNIX
1965                    && mux_path == NULL
1966# endif /* NETUNIX */
1967                    )
1968                {
1969                        if (porttouse)
1970                                port = htons((unsigned short) atoi(porttouse));
1971                        else
1972                                port = htons((unsigned short) atoi(pv[2]));
1973                        if (port == 0)
1974                        {
1975# ifdef NO_GETSERVBYNAME
1976                                syserr("Invalid port number: %s", pv[2]);
1977# else /* NO_GETSERVBYNAME */
1978                                struct servent *sp = getservbyname(pv[2], "tcp");
1979
1980                                if (sp == NULL)
1981                                        syserr("Service %s unknown", pv[2]);
1982                                else
1983                                        port = sp->s_port;
1984# endif /* NO_GETSERVBYNAME */
1985                        }
1986                }
1987
1988                nummxhosts = parse_hostsignature(curhost, mxhosts, m);
1989                if (TimeOuts.to_aconnect > 0)
1990                        enough = curtime() + TimeOuts.to_aconnect;
1991tryhost:
1992                while (hostnum < nummxhosts)
1993                {
1994                        char sep = ':';
1995                        char *endp;
1996                        static char hostbuf[MAXNAME + 1];
1997
1998# if NETINET6
1999                        if (*mxhosts[hostnum] == '[')
2000                        {
2001                                endp = strchr(mxhosts[hostnum] + 1, ']');
2002                                if (endp != NULL)
2003                                        endp = strpbrk(endp + 1, ":,");
2004                        }
2005                        else
2006                                endp = strpbrk(mxhosts[hostnum], ":,");
2007# else /* NETINET6 */
2008                        endp = strpbrk(mxhosts[hostnum], ":,");
2009# endif /* NETINET6 */
2010                        if (endp != NULL)
2011                        {
2012                                sep = *endp;
2013                                *endp = '\0';
2014                        }
2015
2016                        if (hostnum == 1 && skip_back != NULL)
2017                        {
2018                                /*
2019                                **  Coattail piggybacking is no longer an
2020                                **  option with the mail host next to be tried
2021                                **  no longer the lowest MX preference
2022                                **  (hostnum == 1 meaning we're on the second
2023                                **  preference). We do not try to coattail
2024                                **  piggyback more than the first MX preference.
2025                                **  Revert 'tochain' to last location for
2026                                **  coincidental piggybacking. This works this
2027                                **  easily because the q_tchain kept getting
2028                                **  added to the top of the linked list.
2029                                */
2030
2031                                tochain = skip_back;
2032                        }
2033
2034                        if (*mxhosts[hostnum] == '\0')
2035                        {
2036                                syserr("deliver: null host name in signature");
2037                                hostnum++;
2038                                if (endp != NULL)
2039                                        *endp = sep;
2040                                continue;
2041                        }
2042                        (void) sm_strlcpy(hostbuf, mxhosts[hostnum],
2043                                          sizeof hostbuf);
2044                        hostnum++;
2045                        if (endp != NULL)
2046                                *endp = sep;
2047
2048                        /* see if we already know that this host is fried */
2049                        CurHostName = hostbuf;
2050                        mci = mci_get(hostbuf, m);
2051                        if (mci->mci_state != MCIS_CLOSED)
2052                        {
2053                                char *type;
2054
2055                                if (tTd(11, 1))
2056                                {
2057                                        sm_dprintf("openmailer: ");
2058                                        mci_dump(mci, false);
2059                                }
2060                                CurHostName = mci->mci_host;
2061                                if (bitnset(M_LMTP, m->m_flags))
2062                                        type = "L";
2063                                else if (bitset(MCIF_ESMTP, mci->mci_flags))
2064                                        type = "ES";
2065                                else
2066                                        type = "S";
2067                                message("Using cached %sMTP connection to %s via %s...",
2068                                        type, hostbuf, m->m_name);
2069                                mci->mci_deliveries++;
2070                                break;
2071                        }
2072                        mci->mci_mailer = m;
2073                        if (mci->mci_exitstat != EX_OK)
2074                        {
2075                                if (mci->mci_exitstat == EX_TEMPFAIL)
2076                                        goodmxfound = true;
2077                                continue;
2078                        }
2079
2080                        if (mci_lock_host(mci) != EX_OK)
2081                        {
2082                                mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL);
2083                                goodmxfound = true;
2084                                continue;
2085                        }
2086
2087                        /* try the connection */
2088                        sm_setproctitle(true, e, "%s %s: %s",
2089                                        qid_printname(e),
2090                                        hostbuf, "user open");
2091# if NETUNIX
2092                        if (mux_path != NULL)
2093                        {
2094                                message("Connecting to %s via %s...",
2095                                        mux_path, m->m_name);
2096                                i = makeconnection_ds((char *) mux_path, mci);
2097                        }
2098                        else
2099# endif /* NETUNIX */
2100                        {
2101                                if (port == 0)
2102                                        message("Connecting to %s via %s...",
2103                                                hostbuf, m->m_name);
2104                                else
2105                                        message("Connecting to %s port %d via %s...",
2106                                                hostbuf, ntohs(port),
2107                                                m->m_name);
2108                                i = makeconnection(hostbuf, port, mci, e,
2109                                                   enough);
2110                        }
2111                        mci->mci_errno = errno;
2112                        mci->mci_lastuse = curtime();
2113                        mci->mci_deliveries = 0;
2114                        mci->mci_exitstat = i;
2115# if NAMED_BIND
2116                        mci->mci_herrno = h_errno;
2117# endif /* NAMED_BIND */
2118
2119                        /*
2120                        **  Have we tried long enough to get a connection?
2121                        **      If yes, skip to the fallback MX hosts
2122                        **      (if existent).
2123                        */
2124
2125                        if (enough > 0 && mci->mci_lastuse >= enough)
2126                        {
2127                                int h;
2128# if NAMED_BIND
2129                                extern int NumFallBackMXHosts;
2130# else /* NAMED_BIND */
2131                                const int NumFallBackMXHosts = 0;
2132# endif /* NAMED_BIND */
2133
2134                                if (hostnum < nummxhosts && LogLevel > 9)
2135                                        sm_syslog(LOG_INFO, e->e_id,
2136                                                  "Timeout.to_aconnect occurred before exhausting all addresses");
2137
2138                                /* turn off timeout if fallback available */
2139                                if (NumFallBackMXHosts > 0)
2140                                        enough = 0;
2141
2142                                /* skip to a fallback MX host */
2143                                h = nummxhosts - NumFallBackMXHosts;
2144                                if (hostnum < h)
2145                                        hostnum = h;
2146                        }
2147                        if (i == EX_OK)
2148                        {
2149                                goodmxfound = true;
2150                                markstats(e, firstto, STATS_CONNECT);
2151                                mci->mci_state = MCIS_OPENING;
2152                                mci_cache(mci);
2153                                if (TrafficLogFile != NULL)
2154                                        (void) sm_io_fprintf(TrafficLogFile,
2155                                                             SM_TIME_DEFAULT,
2156                                                             "%05d === CONNECT %s\n",
2157                                                             (int) CurrentPid,
2158                                                             hostbuf);
2159                                break;
2160                        }
2161                        else
2162                        {
2163                                if (tTd(11, 1))
2164                                        sm_dprintf("openmailer: makeconnection => stat=%d, errno=%d\n",
2165                                                   i, errno);
2166                                if (i == EX_TEMPFAIL)
2167                                        goodmxfound = true;
2168                                mci_unlock_host(mci);
2169                        }
2170
2171                        /* enter status of this host */
2172                        setstat(i);
2173
2174                        /* should print some message here for -v mode */
2175                }
2176                if (mci == NULL)
2177                {
2178                        syserr("deliver: no host name");
2179                        rcode = EX_SOFTWARE;
2180                        goto give_up;
2181                }
2182                mci->mci_pid = 0;
2183        }
2184        else
2185        {
2186                /* flush any expired connections */
2187                (void) mci_scan(NULL);
2188                mci = NULL;
2189
2190                if (bitnset(M_LMTP, m->m_flags))
2191                {
2192                        /* try to get a cached connection */
2193                        mci = mci_get(m->m_name, m);
2194                        if (mci->mci_host == NULL)
2195                                mci->mci_host = m->m_name;
2196                        CurHostName = mci->mci_host;
2197                        if (mci->mci_state != MCIS_CLOSED)
2198                        {
2199                                message("Using cached LMTP connection for %s...",
2200                                        m->m_name);
2201                                mci->mci_deliveries++;
2202                                goto do_transfer;
2203                        }
2204                }
2205
2206                /* announce the connection to verbose listeners */
2207                if (host == NULL || host[0] == '\0')
2208                        message("Connecting to %s...", m->m_name);
2209                else
2210                        message("Connecting to %s via %s...", host, m->m_name);
2211                if (TrafficLogFile != NULL)
2212                {
2213                        char **av;
2214
2215                        (void) sm_io_fprintf(TrafficLogFile, SM_TIME_DEFAULT,
2216                                             "%05d === EXEC", (int) CurrentPid);
2217                        for (av = pv; *av != NULL; av++)
2218                                (void) sm_io_fprintf(TrafficLogFile,
2219                                                     SM_TIME_DEFAULT, " %s",
2220                                                     *av);
2221                        (void) sm_io_fprintf(TrafficLogFile, SM_TIME_DEFAULT,
2222                                             "\n");
2223                }
2224
2225#if XDEBUG
2226                checkfd012("before creating mail pipe");
2227#endif /* XDEBUG */
2228
2229                /* create a pipe to shove the mail through */
2230                if (pipe(mpvect) < 0)
2231                {
2232                        syserr("%s... openmailer(%s): pipe (to mailer)",
2233                               shortenstring(e->e_to, MAXSHORTSTR), m->m_name);
2234                        if (tTd(11, 1))
2235                                sm_dprintf("openmailer: NULL\n");
2236                        rcode = EX_OSERR;
2237                        goto give_up;
2238                }
2239
2240#if XDEBUG
2241                /* make sure we didn't get one of the standard I/O files */
2242                if (mpvect[0] < 3 || mpvect[1] < 3)
2243                {
2244                        syserr("%s... openmailer(%s): bogus mpvect %d %d",
2245                               shortenstring(e->e_to, MAXSHORTSTR), m->m_name,
2246                               mpvect[0], mpvect[1]);
2247                        printopenfds(true);
2248                        if (tTd(11, 1))
2249                                sm_dprintf("openmailer: NULL\n");
2250                        rcode = EX_OSERR;
2251                        goto give_up;
2252                }
2253
2254                /* make sure system call isn't dead meat */
2255                checkfdopen(mpvect[0], "mpvect[0]");
2256                checkfdopen(mpvect[1], "mpvect[1]");
2257                if (mpvect[0] == mpvect[1] ||
2258                    (e->e_lockfp != NULL &&
2259                     (mpvect[0] == sm_io_getinfo(e->e_lockfp, SM_IO_WHAT_FD,
2260                                                 NULL) ||
2261                      mpvect[1] == sm_io_getinfo(e->e_lockfp, SM_IO_WHAT_FD,
2262                                                 NULL))))
2263                {
2264                        if (e->e_lockfp == NULL)
2265                                syserr("%s... openmailer(%s): overlapping mpvect %d %d",
2266                                       shortenstring(e->e_to, MAXSHORTSTR),
2267                                       m->m_name, mpvect[0], mpvect[1]);
2268                        else
2269                                syserr("%s... openmailer(%s): overlapping mpvect %d %d, lockfp = %d",
2270                                       shortenstring(e->e_to, MAXSHORTSTR),
2271                                       m->m_name, mpvect[0], mpvect[1],
2272                                       sm_io_getinfo(e->e_lockfp,
2273                                                     SM_IO_WHAT_FD, NULL));
2274                }
2275#endif /* XDEBUG */
2276
2277                /* create a return pipe */
2278                if (pipe(rpvect) < 0)
2279                {
2280                        syserr("%s... openmailer(%s): pipe (from mailer)",
2281                               shortenstring(e->e_to, MAXSHORTSTR),
2282                               m->m_name);
2283                        (void) close(mpvect[0]);
2284                        (void) close(mpvect[1]);
2285                        if (tTd(11, 1))
2286                                sm_dprintf("openmailer: NULL\n");
2287                        rcode = EX_OSERR;
2288                        goto give_up;
2289                }
2290#if XDEBUG
2291                checkfdopen(rpvect[0], "rpvect[0]");
2292                checkfdopen(rpvect[1], "rpvect[1]");
2293#endif /* XDEBUG */
2294
2295                /*
2296                **  Actually fork the mailer process.
2297                **      DOFORK is clever about retrying.
2298                **
2299                **      Dispose of SIGCHLD signal catchers that may be laying
2300                **      around so that endmailer will get it.
2301                */
2302
2303                if (e->e_xfp != NULL)   /* for debugging */
2304                        (void) sm_io_flush(e->e_xfp, SM_TIME_DEFAULT);
2305                (void) sm_io_flush(smioout, SM_TIME_DEFAULT);
2306                (void) sm_signal(SIGCHLD, SIG_DFL);
2307
2308
2309                DOFORK(FORK);
2310                /* pid is set by DOFORK */
2311
2312                if (pid < 0)
2313                {
2314                        /* failure */
2315                        syserr("%s... openmailer(%s): cannot fork",
2316                               shortenstring(e->e_to, MAXSHORTSTR), m->m_name);
2317                        (void) close(mpvect[0]);
2318                        (void) close(mpvect[1]);
2319                        (void) close(rpvect[0]);
2320                        (void) close(rpvect[1]);
2321                        if (tTd(11, 1))
2322                                sm_dprintf("openmailer: NULL\n");
2323                        rcode = EX_OSERR;
2324                        goto give_up;
2325                }
2326                else if (pid == 0)
2327                {
2328                        int i;
2329                        int save_errno;
2330                        int sff;
2331                        int new_euid = NO_UID;
2332                        int new_ruid = NO_UID;
2333                        int new_gid = NO_GID;
2334                        char *user = NULL;
2335                        struct stat stb;
2336                        extern int DtableSize;
2337
2338                        CurrentPid = getpid();
2339
2340                        /* clear the events to turn off SIGALRMs */
2341                        sm_clear_events();
2342
2343                        /* Reset global flags */
2344                        RestartRequest = NULL;
2345                        RestartWorkGroup = false;
2346                        ShutdownRequest = NULL;
2347                        PendingSignal = 0;
2348
2349                        if (e->e_lockfp != NULL)
2350                                (void) close(sm_io_getinfo(e->e_lockfp,
2351                                                           SM_IO_WHAT_FD,
2352                                                           NULL));
2353
2354                        /* child -- set up input & exec mailer */
2355                        (void) sm_signal(SIGALRM, sm_signal_noop);
2356                        (void) sm_signal(SIGCHLD, SIG_DFL);
2357                        (void) sm_signal(SIGHUP, SIG_IGN);
2358                        (void) sm_signal(SIGINT, SIG_IGN);
2359                        (void) sm_signal(SIGTERM, SIG_DFL);
2360# ifdef SIGUSR1
2361                        (void) sm_signal(SIGUSR1, sm_signal_noop);
2362# endif /* SIGUSR1 */
2363
2364                        if (m != FileMailer || stat(tochain->q_user, &stb) < 0)
2365                                stb.st_mode = 0;
2366
2367# if HASSETUSERCONTEXT
2368                        /*
2369                        **  Set user resources.
2370                        */
2371
2372                        if (contextaddr != NULL)
2373                        {
2374                                int sucflags;
2375                                struct passwd *pwd;
2376
2377                                if (contextaddr->q_ruser != NULL)
2378                                        pwd = sm_getpwnam(contextaddr->q_ruser);
2379                                else
2380                                        pwd = sm_getpwnam(contextaddr->q_user);
2381                                sucflags = LOGIN_SETRESOURCES|LOGIN_SETPRIORITY;
2382#ifdef LOGIN_SETMAC
2383                                sucflags |= LOGIN_SETMAC;
2384#endif /* LOGIN_SETMAC */
2385                                if (pwd != NULL &&
2386                                    setusercontext(NULL, pwd, pwd->pw_uid,
2387                                                   sucflags) == -1 &&
2388                                    suidwarn)
2389                                {
2390                                        syserr("openmailer: setusercontext() failed");
2391                                        exit(EX_TEMPFAIL);
2392                                }
2393                        }
2394# endif /* HASSETUSERCONTEXT */
2395
2396#if HASNICE
2397                        /* tweak niceness */
2398                        if (m->m_nice != 0)
2399                                (void) nice(m->m_nice);
2400#endif /* HASNICE */
2401
2402                        /* reset group id */
2403                        if (bitnset(M_SPECIFIC_UID, m->m_flags))
2404                                new_gid = m->m_gid;
2405                        else if (bitset(S_ISGID, stb.st_mode))
2406                                new_gid = stb.st_gid;
2407                        else if (ctladdr != NULL && ctladdr->q_gid != 0)
2408                        {
2409                                if (!DontInitGroups)
2410                                {
2411                                        user = ctladdr->q_ruser;
2412                                        if (user == NULL)
2413                                                user = ctladdr->q_user;
2414
2415                                        if (initgroups(user,
2416                                                       ctladdr->q_gid) == -1
2417                                            && suidwarn)
2418                                        {
2419                                                syserr("openmailer: initgroups(%s, %d) failed",
2420                                                        user, ctladdr->q_gid);
2421                                                exit(EX_TEMPFAIL);
2422                                        }
2423                                }
2424                                else
2425                                {
2426                                        GIDSET_T gidset[1];
2427
2428                                        gidset[0] = ctladdr->q_gid;
2429                                        if (setgroups(1, gidset) == -1
2430                                            && suidwarn)
2431                                        {
2432                                                syserr("openmailer: setgroups() failed");
2433                                                exit(EX_TEMPFAIL);
2434                                        }
2435                                }
2436                                new_gid = ctladdr->q_gid;
2437                        }
2438                        else
2439                        {
2440                                if (!DontInitGroups)
2441                                {
2442                                        user = DefUser;
2443                                        if (initgroups(DefUser, DefGid) == -1 &&
2444                                            suidwarn)
2445                                        {
2446                                                syserr("openmailer: initgroups(%s, %d) failed",
2447                                                       DefUser, DefGid);
2448                                                exit(EX_TEMPFAIL);
2449                                        }
2450                                }
2451                                else
2452                                {
2453                                        GIDSET_T gidset[1];
2454
2455                                        gidset[0] = DefGid;
2456                                        if (setgroups(1, gidset) == -1
2457                                            && suidwarn)
2458                                        {
2459                                                syserr("openmailer: setgroups() failed");
2460                                                exit(EX_TEMPFAIL);
2461                                        }
2462                                }
2463                                if (m->m_gid == 0)
2464                                        new_gid = DefGid;
2465                                else
2466                                        new_gid = m->m_gid;
2467                        }
2468                        if (new_gid != NO_GID)
2469                        {
2470                                if (RunAsUid != 0 &&
2471                                    bitnset(M_SPECIFIC_UID, m->m_flags) &&
2472                                    new_gid != getgid() &&
2473                                    new_gid != getegid())
2474                                {
2475                                        /* Only root can change the gid */
2476                                        syserr("openmailer: insufficient privileges to change gid, RunAsUid=%d, new_gid=%d, gid=%d, egid=%d",
2477                                               (int) RunAsUid, (int) new_gid,
2478                                               (int) getgid(), (int) getegid());
2479                                        exit(EX_TEMPFAIL);
2480                                }
2481
2482                                if (setgid(new_gid) < 0 && suidwarn)
2483                                {
2484                                        syserr("openmailer: setgid(%ld) failed",
2485                                               (long) new_gid);
2486                                        exit(EX_TEMPFAIL);
2487                                }
2488                        }
2489
2490                        /* change root to some "safe" directory */
2491                        if (m->m_rootdir != NULL)
2492                        {
2493                                expand(m->m_rootdir, cbuf, sizeof cbuf, e);
2494                                if (tTd(11, 20))
2495                                        sm_dprintf("openmailer: chroot %s\n",
2496                                                   cbuf);
2497                                if (chroot(cbuf) < 0)
2498                                {
2499                                        syserr("openmailer: Cannot chroot(%s)",
2500                                               cbuf);
2501                                        exit(EX_TEMPFAIL);
2502                                }
2503                                if (chdir("/") < 0)
2504                                {
2505                                        syserr("openmailer: cannot chdir(/)");
2506                                        exit(EX_TEMPFAIL);
2507                                }
2508                        }
2509
2510                        /* reset user id */
2511                        endpwent();
2512                        sm_mbdb_terminate();
2513                        if (bitnset(M_SPECIFIC_UID, m->m_flags))
2514                        {
2515                                new_euid = m->m_uid;
2516
2517                                /*
2518                                **  Undo the effects of the uid change in main
2519                                **  for signal handling.  The real uid may
2520                                **  be used by mailer in adding a "From "
2521                                **  line.
2522                                */
2523
2524                                if (RealUid != 0 && RealUid != getuid())
2525                                {
2526# if MAILER_SETUID_METHOD == USE_SETEUID
2527#  if HASSETREUID
2528                                        if (setreuid(RealUid, geteuid()) < 0)
2529                                        {
2530                                                syserr("openmailer: setreuid(%d, %d) failed",
2531                                                       (int) RealUid, (int) geteuid());
2532                                                exit(EX_OSERR);
2533                                        }
2534#  endif /* HASSETREUID */
2535# endif /* MAILER_SETUID_METHOD == USE_SETEUID */
2536# if MAILER_SETUID_METHOD == USE_SETREUID
2537                                        new_ruid = RealUid;
2538# endif /* MAILER_SETUID_METHOD == USE_SETREUID */
2539                                }
2540                        }
2541                        else if (bitset(S_ISUID, stb.st_mode))
2542                                new_ruid = stb.st_uid;
2543                        else if (ctladdr != NULL && ctladdr->q_uid != 0)
2544                                new_ruid = ctladdr->q_uid;
2545                        else if (m->m_uid != 0)
2546                                new_ruid = m->m_uid;
2547                        else
2548                                new_ruid = DefUid;
2549
2550# if _FFR_USE_SETLOGIN
2551                        /* run disconnected from terminal and set login name */
2552                        if (setsid() >= 0 &&
2553                            ctladdr != NULL && ctladdr->q_uid != 0 &&
2554                            new_euid == ctladdr->q_uid)
2555                        {
2556                                struct passwd *pwd;
2557
2558                                pwd = sm_getpwuid(ctladdr->q_uid);
2559                                if (pwd != NULL && suidwarn)
2560                                        (void) setlogin(pwd->pw_name);
2561                                endpwent();
2562                        }
2563# endif /* _FFR_USE_SETLOGIN */
2564
2565                        if (new_euid != NO_UID)
2566                        {
2567                                if (RunAsUid != 0 && new_euid != RunAsUid)
2568                                {
2569                                        /* Only root can change the uid */
2570                                        syserr("openmailer: insufficient privileges to change uid, new_euid=%d, RunAsUid=%d",
2571                                               (int) new_euid, (int) RunAsUid);
2572                                        exit(EX_TEMPFAIL);
2573                                }
2574
2575                                vendor_set_uid(new_euid);
2576# if MAILER_SETUID_METHOD == USE_SETEUID
2577                                if (seteuid(new_euid) < 0 && suidwarn)
2578                                {
2579                                        syserr("openmailer: seteuid(%ld) failed",
2580                                               (long) new_euid);
2581                                        exit(EX_TEMPFAIL);
2582                                }
2583# endif /* MAILER_SETUID_METHOD == USE_SETEUID */
2584# if MAILER_SETUID_METHOD == USE_SETREUID
2585                                if (setreuid(new_ruid, new_euid) < 0 && suidwarn)
2586                                {
2587                                        syserr("openmailer: setreuid(%ld, %ld) failed",
2588                                               (long) new_ruid, (long) new_euid);
2589                                        exit(EX_TEMPFAIL);
2590                                }
2591# endif /* MAILER_SETUID_METHOD == USE_SETREUID */
2592# if MAILER_SETUID_METHOD == USE_SETUID
2593                                if (new_euid != geteuid() && setuid(new_euid) < 0 && suidwarn)
2594                                {
2595                                        syserr("openmailer: setuid(%ld) failed",
2596                                               (long) new_euid);
2597                                        exit(EX_TEMPFAIL);
2598                                }
2599# endif /* MAILER_SETUID_METHOD == USE_SETUID */
2600                        }
2601                        else if (new_ruid != NO_UID)
2602                        {
2603                                vendor_set_uid(new_ruid);
2604                                if (setuid(new_ruid) < 0 && suidwarn)
2605                                {
2606                                        syserr("openmailer: setuid(%ld) failed",
2607                                               (long) new_ruid);
2608                                        exit(EX_TEMPFAIL);
2609                                }
2610                        }
2611
2612                        if (tTd(11, 2))
2613                                sm_dprintf("openmailer: running as r/euid=%d/%d, r/egid=%d/%d\n",
2614                                           (int) getuid(), (int) geteuid(),
2615                                           (int) getgid(), (int) getegid());
2616
2617                        /* move into some "safe" directory */
2618                        if (m->m_execdir != NULL)
2619                        {
2620                                char *q;
2621
2622                                for (p = m->m_execdir; p != NULL; p = q)
2623                                {
2624                                        q = strchr(p, ':');
2625                                        if (q != NULL)
2626                                                *q = '\0';
2627                                        expand(p, cbuf, sizeof cbuf, e);
2628                                        if (q != NULL)
2629                                                *q++ = ':';
2630                                        if (tTd(11, 20))
2631                                                sm_dprintf("openmailer: trydir %s\n",
2632                                                           cbuf);
2633                                        if (cbuf[0] != '\0' &&
2634                                            chdir(cbuf) >= 0)
2635                                                break;
2636                                }
2637                        }
2638
2639                        /* Check safety of program to be run */
2640                        sff = SFF_ROOTOK|SFF_EXECOK;
2641                        if (!bitnset(DBS_RUNWRITABLEPROGRAM,
2642                                     DontBlameSendmail))
2643                                sff |= SFF_NOGWFILES|SFF_NOWWFILES;
2644                        if (bitnset(DBS_RUNPROGRAMINUNSAFEDIRPATH,
2645                                    DontBlameSendmail))
2646                                sff |= SFF_NOPATHCHECK;
2647                        else
2648                                sff |= SFF_SAFEDIRPATH;
2649                        ret = safefile(m->m_mailer, getuid(), getgid(),
2650                                       user, sff, 0, NULL);
2651                        if (ret != 0)
2652                                sm_syslog(LOG_INFO, e->e_id,
2653                                          "Warning: program %s unsafe: %s",
2654                                          m->m_mailer, sm_errstring(ret));
2655
2656                        /* arrange to filter std & diag output of command */
2657                        (void) close(rpvect[0]);
2658                        if (dup2(rpvect[1], STDOUT_FILENO) < 0)
2659                        {
2660                                syserr("%s... openmailer(%s): cannot dup pipe %d for stdout",
2661                                       shortenstring(e->e_to, MAXSHORTSTR),
2662                                       m->m_name, rpvect[1]);
2663                                _exit(EX_OSERR);
2664                        }
2665                        (void) close(rpvect[1]);
2666
2667                        if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0)
2668                        {
2669                                syserr("%s... openmailer(%s): cannot dup stdout for stderr",
2670                                       shortenstring(e->e_to, MAXSHORTSTR),
2671                                       m->m_name);
2672                                _exit(EX_OSERR);
2673                        }
2674
2675                        /* arrange to get standard input */
2676                        (void) close(mpvect[1]);
2677                        if (dup2(mpvect[0], STDIN_FILENO) < 0)
2678                        {
2679                                syserr("%s... openmailer(%s): cannot dup pipe %d for stdin",
2680                                       shortenstring(e->e_to, MAXSHORTSTR),
2681                                       m->m_name, mpvect[0]);
2682                                _exit(EX_OSERR);
2683                        }
2684                        (void) close(mpvect[0]);
2685
2686                        /* arrange for all the files to be closed */
2687                        for (i = 3; i < DtableSize; i++)
2688                        {
2689                                register int j;
2690
2691                                if ((j = fcntl(i, F_GETFD, 0)) != -1)
2692                                        (void) fcntl(i, F_SETFD,
2693                                                     j | FD_CLOEXEC);
2694                        }
2695
2696# if !_FFR_USE_SETLOGIN
2697                        /* run disconnected from terminal */
2698                        (void) setsid();
2699# endif /* !_FFR_USE_SETLOGIN */
2700
2701                        /* try to execute the mailer */
2702                        (void) execve(m->m_mailer, (ARGV_T) pv,
2703                                      (ARGV_T) UserEnviron);
2704                        save_errno = errno;
2705                        syserr("Cannot exec %s", m->m_mailer);
2706                        if (bitnset(M_LOCALMAILER, m->m_flags) ||
2707                            transienterror(save_errno))
2708                                _exit(EX_OSERR);
2709                        _exit(EX_UNAVAILABLE);
2710                }
2711
2712                /*
2713                **  Set up return value.
2714                */
2715
2716                if (mci == NULL)
2717                {
2718                        if (clever)
2719                        {
2720                                /*
2721                                **  Allocate from general heap, not
2722                                **  envelope rpool, because this mci
2723                                **  is going to be cached.
2724                                */
2725
2726                                mci = mci_new(NULL);
2727                        }
2728                        else
2729                        {
2730                                /*
2731                                **  Prevent a storage leak by allocating
2732                                **  this from the envelope rpool.
2733                                */
2734
2735                                mci = mci_new(e->e_rpool);
2736                        }
2737                }
2738                mci->mci_mailer = m;
2739                if (clever)
2740                {
2741                        mci->mci_state = MCIS_OPENING;
2742                        mci_cache(mci);
2743                }
2744                else
2745                {
2746                        mci->mci_state = MCIS_OPEN;
2747                }
2748                mci->mci_pid = pid;
2749                (void) close(mpvect[0]);
2750                mci->mci_out = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT,
2751                                          (void *) &(mpvect[1]), SM_IO_WRONLY,
2752                                          NULL);
2753                if (mci->mci_out == NULL)
2754                {
2755                        syserr("deliver: cannot create mailer output channel, fd=%d",
2756                               mpvect[1]);
2757                        (void) close(mpvect[1]);
2758                        (void) close(rpvect[0]);
2759                        (void) close(rpvect[1]);
2760                        rcode = EX_OSERR;
2761                        goto give_up;
2762                }
2763
2764                (void) close(rpvect[1]);
2765                mci->mci_in = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT,
2766                                         (void *) &(rpvect[0]), SM_IO_RDONLY,
2767                                         NULL);
2768                if (mci->mci_in == NULL)
2769                {
2770                        syserr("deliver: cannot create mailer input channel, fd=%d",
2771                               mpvect[1]);
2772                        (void) close(rpvect[0]);
2773                        (void) sm_io_close(mci->mci_out, SM_TIME_DEFAULT);
2774                        mci->mci_out = NULL;
2775                        rcode = EX_OSERR;
2776                        goto give_up;
2777                }
2778        }
2779
2780        /*
2781        **  If we are in SMTP opening state, send initial protocol.
2782        */
2783
2784        if (bitnset(M_7BITS, m->m_flags) &&
2785            (!clever || mci->mci_state == MCIS_OPENING))
2786                mci->mci_flags |= MCIF_7BIT;
2787        if (clever && mci->mci_state != MCIS_CLOSED)
2788        {
2789# if STARTTLS || SASL
2790                int dotpos;
2791                char *srvname;
2792                extern SOCKADDR CurHostAddr;
2793# endif /* STARTTLS || SASL */
2794
2795# if SASL
2796#  define DONE_AUTH(f)          bitset(MCIF_AUTHACT, f)
2797# endif /* SASL */
2798# if STARTTLS
2799#  define DONE_STARTTLS(f)      bitset(MCIF_TLSACT, f)
2800# endif /* STARTTLS */
2801# define ONLY_HELO(f)           bitset(MCIF_ONLY_EHLO, f)
2802# define SET_HELO(f)            f |= MCIF_ONLY_EHLO
2803# define CLR_HELO(f)            f &= ~MCIF_ONLY_EHLO
2804
2805# if STARTTLS || SASL
2806                /* don't use CurHostName, it is changed in many places */
2807                if (mci->mci_host != NULL)
2808                {
2809                        srvname = mci->mci_host;
2810                        dotpos = strlen(srvname) - 1;
2811                        if (dotpos >= 0)
2812                        {
2813                                if (srvname[dotpos] == '.')
2814                                        srvname[dotpos] = '\0';
2815                                else
2816                                        dotpos = -1;
2817                        }
2818                }
2819                else if (mci->mci_mailer != NULL)
2820                {
2821                        srvname = mci->mci_mailer->m_name;
2822                        dotpos = -1;
2823                }
2824                else
2825                {
2826                        srvname = "local";
2827                        dotpos = -1;
2828                }
2829
2830                /* don't set {server_name} to NULL or "": see getauth() */
2831                macdefine(&mci->mci_macro, A_TEMP, macid("{server_name}"),
2832                          srvname);
2833
2834                /* CurHostAddr is set by makeconnection() and mci_get() */
2835                if (CurHostAddr.sa.sa_family != 0)
2836                {
2837                        macdefine(&mci->mci_macro, A_TEMP,
2838                                  macid("{server_addr}"),
2839                                  anynet_ntoa(&CurHostAddr));
2840                }
2841                else if (mci->mci_mailer != NULL)
2842                {
2843                        /* mailer name is unique, use it as address */
2844                        macdefine(&mci->mci_macro, A_PERM,
2845                                  macid("{server_addr}"),
2846                                  mci->mci_mailer->m_name);
2847                }
2848                else
2849                {
2850                        /* don't set it to NULL or "": see getauth() */
2851                        macdefine(&mci->mci_macro, A_PERM,
2852                                  macid("{server_addr}"), "0");
2853                }
2854
2855                /* undo change of srvname (mci->mci_host) */
2856                if (dotpos >= 0)
2857                        srvname[dotpos] = '.';
2858
2859reconnect:      /* after switching to an encrypted connection */
2860# endif /* STARTTLS || SASL */
2861
2862                /* set the current connection information */
2863                e->e_mci = mci;
2864# if SASL
2865                mci->mci_saslcap = NULL;
2866# endif /* SASL */
2867                smtpinit(m, mci, e, ONLY_HELO(mci->mci_flags));
2868                CLR_HELO(mci->mci_flags);
2869
2870                if (IS_DLVR_RETURN(e))
2871                {
2872                        /*
2873                        **  Check whether other side can deliver e-mail
2874                        **  fast enough
2875                        */
2876
2877                        if (!bitset(MCIF_DLVR_BY, mci->mci_flags))
2878                        {
2879                                e->e_status = "5.4.7";
2880                                usrerrenh(e->e_status,
2881                                          "554 Server does not support Deliver By");
2882                                rcode = EX_UNAVAILABLE;
2883                                goto give_up;
2884                        }
2885                        if (e->e_deliver_by > 0 &&
2886                            e->e_deliver_by - (curtime() - e->e_ctime) <
2887                            mci->mci_min_by)
2888                        {
2889                                e->e_status = "5.4.7";
2890                                usrerrenh(e->e_status,
2891                                          "554 Message can't be delivered in time; %ld < %ld",
2892                                          e->e_deliver_by - (curtime() - e->e_ctime),
2893                                          mci->mci_min_by);
2894                                rcode = EX_UNAVAILABLE;
2895                                goto give_up;
2896                        }
2897                }
2898
2899# if STARTTLS
2900                /* first TLS then AUTH to provide a security layer */
2901                if (mci->mci_state != MCIS_CLOSED &&
2902                    !DONE_STARTTLS(mci->mci_flags))
2903                {
2904                        int olderrors;
2905                        bool usetls;
2906                        bool saveQuickAbort = QuickAbort;
2907                        bool saveSuprErrs = SuprErrs;
2908                        char *host = NULL;
2909
2910                        rcode = EX_OK;
2911                        usetls = bitset(MCIF_TLS, mci->mci_flags);
2912                        if (usetls)
2913                                usetls = !iscltflgset(e, D_NOTLS);
2914
2915                        if (usetls)
2916                        {
2917                                host = macvalue(macid("{server_name}"), e);
2918                                olderrors = Errors;
2919                                QuickAbort = false;
2920                                SuprErrs = true;
2921                                if (rscheck("try_tls", host, NULL, e,
2922                                            RSF_RMCOMM, 7, host, NOQID) != EX_OK
2923                                    || Errors > olderrors)
2924                                        usetls = false;
2925                                SuprErrs = saveSuprErrs;
2926                                QuickAbort = saveQuickAbort;
2927                        }
2928
2929                        if (usetls)
2930                        {
2931                                if ((rcode = starttls(m, mci, e)) == EX_OK)
2932                                {
2933                                        /* start again without STARTTLS */
2934                                        mci->mci_flags |= MCIF_TLSACT;
2935                                }
2936                                else
2937                                {
2938                                        char *s;
2939
2940                                        /*
2941                                        **  TLS negotation failed, what to do?
2942                                        **  fall back to unencrypted connection
2943                                        **  or abort? How to decide?
2944                                        **  set a macro and call a ruleset.
2945                                        */
2946
2947                                        mci->mci_flags &= ~MCIF_TLS;
2948                                        switch (rcode)
2949                                        {
2950                                          case EX_TEMPFAIL:
2951                                                s = "TEMP";
2952                                                break;
2953                                          case EX_USAGE:
2954                                                s = "USAGE";
2955                                                break;
2956                                          case EX_PROTOCOL:
2957                                                s = "PROTOCOL";
2958                                                break;
2959                                          case EX_SOFTWARE:
2960                                                s = "SOFTWARE";
2961                                                break;
2962
2963                                          /* everything else is a failure */
2964                                          default:
2965                                                s = "FAILURE";
2966                                                rcode = EX_TEMPFAIL;
2967                                        }
2968                                        macdefine(&e->e_macro, A_PERM,
2969                                                  macid("{verify}"), s);
2970                                }
2971                        }
2972                        else
2973                                macdefine(&e->e_macro, A_PERM,
2974                                          macid("{verify}"), "NONE");
2975                        olderrors = Errors;
2976                        QuickAbort = false;
2977                        SuprErrs = true;
2978
2979                        /*
2980                        **  rcode == EX_SOFTWARE is special:
2981                        **  the TLS negotation failed
2982                        **  we have to drop the connection no matter what
2983                        **  However, we call tls_server to give it the chance
2984                        **  to log the problem and return an appropriate
2985                        **  error code.
2986                        */
2987
2988                        if (rscheck("tls_server",
2989                                    macvalue(macid("{verify}"), e),
2990                                    NULL, e, RSF_RMCOMM|RSF_COUNT, 5,
2991                                    host, NOQID) != EX_OK ||
2992                            Errors > olderrors ||
2993                            rcode == EX_SOFTWARE)
2994                        {
2995                                char enhsc[ENHSCLEN];
2996                                extern char MsgBuf[];
2997
2998                                if (ISSMTPCODE(MsgBuf) &&
2999                                    extenhsc(MsgBuf + 4, ' ', enhsc) > 0)
3000                                {
3001                                        p = sm_rpool_strdup_x(e->e_rpool,
3002                                                              MsgBuf);
3003                                }
3004                                else
3005                                {
3006                                        p = "403 4.7.0 server not authenticated.";
3007                                        (void) sm_strlcpy(enhsc, "4.7.0",
3008                                                          sizeof enhsc);
3009                                }
3010                                SuprErrs = saveSuprErrs;
3011                                QuickAbort = saveQuickAbort;
3012
3013                                if (rcode == EX_SOFTWARE)
3014                                {
3015                                        /* drop the connection */
3016                                        mci->mci_state = MCIS_QUITING;
3017                                        if (mci->mci_in != NULL)
3018                                        {
3019                                                (void) sm_io_close(mci->mci_in,
3020                                                                   SM_TIME_DEFAULT);
3021                                                mci->mci_in = NULL;
3022                                        }
3023                                        mci->mci_flags &= ~MCIF_TLSACT;
3024                                        (void) endmailer(mci, e, pv);
3025                                }
3026                                else
3027                                {
3028                                        /* abort transfer */
3029                                        smtpquit(m, mci, e);
3030                                }
3031
3032                                /* avoid bogus error msg */
3033                                mci->mci_errno = 0;
3034
3035                                /* temp or permanent failure? */
3036                                rcode = (*p == '4') ? EX_TEMPFAIL
3037                                                    : EX_UNAVAILABLE;
3038                                mci_setstat(mci, rcode, enhsc, p);
3039
3040                                /*
3041                                **  hack to get the error message into
3042                                **  the envelope (done in giveresponse())
3043                                */
3044
3045                                (void) sm_strlcpy(SmtpError, p,
3046                                                  sizeof SmtpError);
3047                        }
3048                        QuickAbort = saveQuickAbort;
3049                        SuprErrs = saveSuprErrs;
3050                        if (DONE_STARTTLS(mci->mci_flags) &&
3051                            mci->mci_state != MCIS_CLOSED)
3052                        {
3053                                SET_HELO(mci->mci_flags);
3054                                mci->mci_flags &= ~MCIF_EXTENS;
3055                                goto reconnect;
3056                        }
3057                }
3058# endif /* STARTTLS */
3059# if SASL
3060                /* if other server supports authentication let's authenticate */
3061                if (mci->mci_state != MCIS_CLOSED &&
3062                    mci->mci_saslcap != NULL &&
3063                    !DONE_AUTH(mci->mci_flags) && !iscltflgset(e, D_NOAUTH))
3064                {
3065                        /* Should we require some minimum authentication? */
3066                        if ((ret = smtpauth(m, mci, e)) == EX_OK)
3067                        {
3068                                int result;
3069                                sasl_ssf_t *ssf = NULL;
3070
3071                                /* Get security strength (features) */
3072                                result = sasl_getprop(mci->mci_conn, SASL_SSF,
3073# if SASL >= 20000
3074                                                      (const void **) &ssf);
3075# else /* SASL >= 20000 */
3076                                                      (void **) &ssf);
3077# endif /* SASL >= 20000 */
3078
3079                                /* XXX authid? */
3080                                if (LogLevel > 9)
3081                                        sm_syslog(LOG_INFO, NOQID,
3082                                                  "AUTH=client, relay=%.100s, mech=%.16s, bits=%d",
3083                                                  mci->mci_host,
3084                                                  macvalue(macid("{auth_type}"), e),
3085                                                  result == SASL_OK ? *ssf : 0);
3086
3087                                /*
3088                                **  Only switch to encrypted connection
3089                                **  if a security layer has been negotiated
3090                                */
3091
3092                                if (result == SASL_OK && *ssf > 0)
3093                                {
3094                                        /*
3095                                        **  Convert I/O layer to use SASL.
3096                                        **  If the call fails, the connection
3097                                        **  is aborted.
3098                                        */
3099
3100                                        if (sfdcsasl(&mci->mci_in,
3101                                                     &mci->mci_out,
3102                                                     mci->mci_conn) == 0)
3103                                        {
3104                                                mci->mci_flags &= ~MCIF_EXTENS;
3105                                                mci->mci_flags |= MCIF_AUTHACT|
3106                                                                  MCIF_ONLY_EHLO;
3107                                                goto reconnect;
3108                                        }
3109                                        syserr("AUTH TLS switch failed in client");
3110                                }
3111                                /* else? XXX */
3112                                mci->mci_flags |= MCIF_AUTHACT;
3113
3114                        }
3115                        else if (ret == EX_TEMPFAIL)
3116                        {
3117                                if (LogLevel > 8)
3118                                        sm_syslog(LOG_ERR, NOQID,
3119                                                  "AUTH=client, relay=%.100s, temporary failure, connection abort",
3120                                                  mci->mci_host);
3121                                smtpquit(m, mci, e);
3122
3123                                /* avoid bogus error msg */
3124                                mci->mci_errno = 0;
3125                                rcode = EX_TEMPFAIL;
3126                                mci_setstat(mci, rcode, "4.7.1", p);
3127
3128                                /*
3129                                **  hack to get the error message into
3130                                **  the envelope (done in giveresponse())
3131                                */
3132
3133                                (void) sm_strlcpy(SmtpError,
3134                                                  "Temporary AUTH failure",
3135                                                  sizeof SmtpError);
3136                        }
3137                }
3138# endif /* SASL */
3139        }
3140
3141
3142do_transfer:
3143        /* clear out per-message flags from connection structure */
3144        mci->mci_flags &= ~(MCIF_CVT7TO8|MCIF_CVT8TO7);
3145
3146        if (bitset(EF_HAS8BIT, e->e_flags) &&
3147            !bitset(EF_DONT_MIME, e->e_flags) &&
3148            bitnset(M_7BITS, m->m_flags))
3149                mci->mci_flags |= MCIF_CVT8TO7;
3150
3151#if MIME7TO8
3152        if (bitnset(M_MAKE8BIT, m->m_flags) &&
3153            !bitset(MCIF_7BIT, mci->mci_flags) &&
3154            (p = hvalue("Content-Transfer-Encoding", e->e_header)) != NULL &&
3155             (sm_strcasecmp(p, "quoted-printable") == 0 ||
3156              sm_strcasecmp(p, "base64") == 0) &&
3157            (p = hvalue("Content-Type", e->e_header)) != NULL)
3158        {
3159                /* may want to convert 7 -> 8 */
3160                /* XXX should really parse it here -- and use a class XXX */
3161                if (sm_strncasecmp(p, "text/plain", 10) == 0 &&
3162                    (p[10] == '\0' || p[10] == ' ' || p[10] == ';'))
3163                        mci->mci_flags |= MCIF_CVT7TO8;
3164        }
3165#endif /* MIME7TO8 */
3166
3167        if (tTd(11, 1))
3168        {
3169                sm_dprintf("openmailer: ");
3170                mci_dump(mci, false);
3171        }
3172
3173#if _FFR_CLIENT_SIZE
3174        /*
3175        **  See if we know the maximum size and
3176        **  abort if the message is too big.
3177        **
3178        **  NOTE: _FFR_CLIENT_SIZE is untested.
3179        */
3180
3181        if (bitset(MCIF_SIZE, mci->mci_flags) &&
3182            mci->mci_maxsize > 0 &&
3183            e->e_msgsize > mci->mci_maxsize)
3184        {
3185                e->e_flags |= EF_NO_BODY_RETN;
3186                if (bitnset(M_LOCALMAILER, m->m_flags))
3187                        e->e_status = "5.2.3";
3188                else
3189                        e->e_status = "5.3.4";
3190
3191                usrerrenh(e->e_status,
3192                          "552 Message is too large; %ld bytes max",
3193                          mci->mci_maxsize);
3194                rcode = EX_DATAERR;
3195
3196                /* Need an e_message for error */
3197                (void) sm_snprintf(SmtpError, sizeof SmtpError,
3198                                   "Message is too large; %ld bytes max",
3199                                   mci->mci_maxsize);
3200                goto give_up;
3201        }
3202#endif /* _FFR_CLIENT_SIZE */
3203
3204        if (mci->mci_state != MCIS_OPEN)
3205        {
3206                /* couldn't open the mailer */
3207                rcode = mci->mci_exitstat;
3208                errno = mci->mci_errno;
3209                SM_SET_H_ERRNO(mci->mci_herrno);
3210                if (rcode == EX_OK)
3211                {
3212                        /* shouldn't happen */
3213                        syserr("554 5.3.5 deliver: mci=%lx rcode=%d errno=%d state=%d sig=%s",
3214                               (unsigned long) mci, rcode, errno,
3215                               mci->mci_state, firstsig);
3216                        mci_dump_all(true);
3217                        rcode = EX_SOFTWARE;
3218                }
3219                else if (nummxhosts > hostnum)
3220                {
3221                        /* try next MX site */
3222                        goto tryhost;
3223                }
3224        }
3225        else if (!clever)
3226        {
3227                bool ok;
3228
3229                /*
3230                **  Format and send message.
3231                */
3232
3233                rcode = EX_OK;
3234                errno = 0;
3235                ok = putfromline(mci, e);
3236                if (ok)
3237                        ok = (*e->e_puthdr)(mci, e->e_header, e, M87F_OUTER);
3238                if (ok)
3239                        ok = (*e->e_putbody)(mci, e, NULL);
3240
3241                /*
3242                **  Ignore an I/O error that was caused by EPIPE.
3243                **  Some broken mailers don't read the entire body
3244                **  but just exit() thus causing an I/O error.
3245                */
3246
3247                if (!ok && (sm_io_error(mci->mci_out) && errno == EPIPE))
3248                        ok = true;
3249
3250                /* (always) get the exit status */
3251                rcode = endmailer(mci, e, pv);
3252                if (!ok)
3253                        rcode = EX_TEMPFAIL;
3254                if (rcode == EX_TEMPFAIL && SmtpError[0] == '\0')
3255                {
3256                        /*
3257                        **  Need an e_message for mailq display.
3258                        **  We set SmtpError as
3259                        */
3260
3261                        (void) sm_snprintf(SmtpError, sizeof SmtpError,
3262                                           "%s mailer (%s) exited with EX_TEMPFAIL",
3263                                           m->m_name, m->m_mailer);
3264                }
3265        }
3266        else
3267        {
3268                /*
3269                **  Send the MAIL FROM: protocol
3270                */
3271
3272                /* XXX this isn't pipelined... */
3273                rcode = smtpmailfrom(m, mci, e);
3274                if (rcode == EX_OK)
3275                {
3276                        register int i;
3277# if PIPELINING
3278                        ADDRESS *volatile pchain;
3279# endif /* PIPELINING */
3280
3281                        /* send the recipient list */
3282                        tobuf[0] = '\0';
3283                        mci->mci_retryrcpt = false;
3284                        mci->mci_tolist = tobuf;
3285# if PIPELINING
3286                        pchain = NULL;
3287                        mci->mci_nextaddr = NULL;
3288# endif /* PIPELINING */
3289
3290                        for (to = tochain; to != NULL; to = to->q_tchain)
3291                        {
3292                                if (!QS_IS_UNMARKED(to->q_state))
3293                                        continue;
3294
3295                                /* mark recipient state as "ok so far" */
3296                                to->q_state = QS_OK;
3297                                e->e_to = to->q_paddr;
3298# if STARTTLS
3299                                i = rscheck("tls_rcpt", to->q_user, NULL, e,
3300                                            RSF_RMCOMM|RSF_COUNT, 3,
3301                                            mci->mci_host, e->e_id);
3302                                if (i != EX_OK)
3303                                {
3304                                        markfailure(e, to, mci, i, false);
3305                                        giveresponse(i, to->q_status,  m, mci,
3306                                                     ctladdr, xstart, e, to);
3307                                        if (i == EX_TEMPFAIL)
3308                                        {
3309                                                mci->mci_retryrcpt = true;
3310                                                to->q_state = QS_RETRY;
3311                                        }
3312                                        continue;
3313                                }
3314# endif /* STARTTLS */
3315
3316                                i = smtprcpt(to, m, mci, e, ctladdr, xstart);
3317# if PIPELINING
3318                                if (i == EX_OK &&
3319                                    bitset(MCIF_PIPELINED, mci->mci_flags))
3320                                {
3321                                        /*
3322                                        **  Add new element to list of
3323                                        **  recipients for pipelining.
3324                                        */
3325
3326                                        to->q_pchain = NULL;
3327                                        if (mci->mci_nextaddr == NULL)
3328                                                mci->mci_nextaddr = to;
3329                                        if (pchain == NULL)
3330                                                pchain = to;
3331                                        else
3332                                        {
3333                                                pchain->q_pchain = to;
3334                                                pchain = pchain->q_pchain;
3335                                        }
3336                                }
3337# endif /* PIPELINING */
3338                                if (i != EX_OK)
3339                                {
3340                                        markfailure(e, to, mci, i, false);
3341                                        giveresponse(i, to->q_status, m, mci,
3342                                                     ctladdr, xstart, e, to);
3343                                        if (i == EX_TEMPFAIL)
3344                                                to->q_state = QS_RETRY;
3345                                }
3346                        }
3347
3348                        /* No recipients in list and no missing responses? */
3349                        if (tobuf[0] == '\0'
3350# if PIPELINING
3351                            && mci->mci_nextaddr == NULL
3352# endif /* PIPELINING */
3353                           )
3354                        {
3355                                rcode = EX_OK;
3356                                e->e_to = NULL;
3357                                if (bitset(MCIF_CACHED, mci->mci_flags))
3358                                        smtprset(m, mci, e);
3359                        }
3360                        else
3361                        {
3362                                e->e_to = tobuf + 1;
3363                                rcode = smtpdata(m, mci, e, ctladdr, xstart);
3364                        }
3365                }
3366                if (rcode == EX_TEMPFAIL && nummxhosts > hostnum)
3367                {
3368                        /* try next MX site */
3369                        goto tryhost;
3370                }
3371        }
3372#if NAMED_BIND
3373        if (ConfigLevel < 2)
3374                _res.options |= RES_DEFNAMES | RES_DNSRCH;      /* XXX */
3375#endif /* NAMED_BIND */
3376
3377        if (tTd(62, 1))
3378                checkfds("after delivery");
3379
3380        /*
3381        **  Do final status disposal.
3382        **      We check for something in tobuf for the SMTP case.
3383        **      If we got a temporary failure, arrange to queue the
3384        **              addressees.
3385        */
3386
3387  give_up:
3388        if (bitnset(M_LMTP, m->m_flags))
3389        {
3390                lmtp_rcode = rcode;
3391                tobuf[0] = '\0';
3392                anyok = false;
3393                strsize = 0;
3394        }
3395        else
3396                anyok = rcode == EX_OK;
3397
3398        for (to = tochain; to != NULL; to = to->q_tchain)
3399        {
3400                /* see if address already marked */
3401                if (!QS_IS_OK(to->q_state))
3402                        continue;
3403
3404                /* if running LMTP, get the status for each address */
3405                if (bitnset(M_LMTP, m->m_flags))
3406                {
3407                        if (lmtp_rcode == EX_OK)
3408                                rcode = smtpgetstat(m, mci, e);
3409                        if (rcode == EX_OK)
3410                        {
3411                                strsize += sm_strlcat2(tobuf + strsize, ",",
3412                                                to->q_paddr,
3413                                                tobufsize - strsize);
3414                                SM_ASSERT(strsize < tobufsize);
3415                                anyok = true;
3416                        }
3417                        else
3418                        {
3419                                e->e_to = to->q_paddr;
3420                                markfailure(e, to, mci, rcode, true);
3421                                giveresponse(rcode, to->q_status, m, mci,
3422                                             ctladdr, xstart, e, to);
3423                                e->e_to = tobuf + 1;
3424                                continue;
3425                        }
3426                }
3427                else
3428                {
3429                        /* mark bad addresses */
3430                        if (rcode != EX_OK)
3431                        {
3432                                if (goodmxfound && rcode == EX_NOHOST)
3433                                        rcode = EX_TEMPFAIL;
3434                                markfailure(e, to, mci, rcode, true);
3435                                continue;
3436                        }
3437                }
3438
3439                /* successful delivery */
3440                to->q_state = QS_SENT;
3441                to->q_statdate = curtime();
3442                e->e_nsent++;
3443
3444                /*
3445                **  Checkpoint the send list every few addresses
3446                */
3447
3448                if (CheckpointInterval > 0 && e->e_nsent >= CheckpointInterval)
3449                {
3450                        queueup(e, false, false);
3451                        e->e_nsent = 0;
3452                }
3453
3454                if (bitnset(M_LOCALMAILER, m->m_flags) &&
3455                    bitset(QPINGONSUCCESS, to->q_flags))
3456                {
3457                        to->q_flags |= QDELIVERED;
3458                        to->q_status = "2.1.5";
3459                        (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT,
3460                                             "%s... Successfully delivered\n",
3461                                             to->q_paddr);
3462                }
3463                else if (bitset(QPINGONSUCCESS, to->q_flags) &&
3464                         bitset(QPRIMARY, to->q_flags) &&
3465                         !bitset(MCIF_DSN, mci->mci_flags))
3466                {
3467                        to->q_flags |= QRELAYED;
3468                        (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT,
3469                                             "%s... relayed; expect no further notifications\n",
3470                                             to->q_paddr);
3471                }
3472                else if (IS_DLVR_NOTIFY(e) &&
3473                         !bitset(MCIF_DLVR_BY, mci->mci_flags) &&
3474                         bitset(QPRIMARY, to->q_flags) &&
3475                         (!bitset(QHASNOTIFY, to->q_flags) ||
3476                          bitset(QPINGONSUCCESS, to->q_flags) ||
3477                          bitset(QPINGONFAILURE, to->q_flags) ||
3478                          bitset(QPINGONDELAY, to->q_flags)))
3479                {
3480                        /* RFC 2852, 4.1.4.2: no NOTIFY, or not NEVER */
3481                        to->q_flags |= QBYNRELAY;
3482                        (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT,
3483                                             "%s... Deliver-by notify: relayed\n",
3484                                             to->q_paddr);
3485                }
3486                else if (IS_DLVR_TRACE(e) &&
3487                         (!bitset(QHASNOTIFY, to->q_flags) ||
3488                          bitset(QPINGONSUCCESS, to->q_flags) ||
3489                          bitset(QPINGONFAILURE, to->q_flags) ||
3490                          bitset(QPINGONDELAY, to->q_flags)) &&
3491                         bitset(QPRIMARY, to->q_flags))
3492                {
3493                        /* RFC 2852, 4.1.4: no NOTIFY, or not NEVER */
3494                        to->q_flags |= QBYTRACE;
3495                        (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT,
3496                                             "%s... Deliver-By trace: relayed\n",
3497                                             to->q_paddr);
3498                }
3499        }
3500
3501        if (bitnset(M_LMTP, m->m_flags))
3502        {
3503                /*
3504                **  Global information applies to the last recipient only;
3505                **  clear it out to avoid bogus errors.
3506                */
3507
3508                rcode = EX_OK;
3509                e->e_statmsg = NULL;
3510
3511                /* reset the mci state for the next transaction */
3512                if (mci != NULL &&
3513                    (mci->mci_state == MCIS_MAIL ||
3514                     mci->mci_state == MCIS_RCPT ||
3515                     mci->mci_state == MCIS_DATA))
3516                        mci->mci_state = MCIS_OPEN;
3517        }
3518
3519        if (tobuf[0] != '\0')
3520        {
3521                giveresponse(rcode, NULL, m, mci, ctladdr, xstart, e, tochain);
3522#if 0
3523                /*
3524                **  This code is disabled for now because I am not
3525                **  sure that copying status from the first recipient
3526                **  to all non-status'ed recipients is a good idea.
3527                */
3528
3529                if (tochain->q_message != NULL &&
3530                    !bitnset(M_LMTP, m->m_flags) && rcode != EX_OK)
3531                {
3532                        for (to = tochain->q_tchain; to != NULL;
3533                             to = to->q_tchain)
3534                        {
3535                                /* see if address already marked */
3536                                if (QS_IS_QUEUEUP(to->q_state) &&
3537                                    to->q_message == NULL)
3538                                        to->q_message = sm_rpool_strdup_x(e->e_rpool,
3539                                                        tochain->q_message);
3540                        }
3541                }
3542#endif /* 0 */
3543        }
3544        if (anyok)
3545                markstats(e, tochain, STATS_NORMAL);
3546        mci_store_persistent(mci);
3547
3548        /* Some recipients were tempfailed, try them on the next host */
3549        if (mci != NULL && mci->mci_retryrcpt && nummxhosts > hostnum)
3550        {
3551                /* try next MX site */
3552                goto tryhost;
3553        }
3554
3555        /* now close the connection */
3556        if (clever && mci != NULL && mci->mci_state != MCIS_CLOSED &&
3557            !bitset(MCIF_CACHED, mci->mci_flags))
3558                smtpquit(m, mci, e);
3559
3560cleanup: ;
3561        }
3562        SM_FINALLY
3563        {
3564                /*
3565                **  Restore state and return.
3566                */
3567#if XDEBUG
3568                char wbuf[MAXLINE];
3569
3570                /* make absolutely certain 0, 1, and 2 are in use */
3571                (void) sm_snprintf(wbuf, sizeof wbuf,
3572                                   "%s... end of deliver(%s)",
3573                                   e->e_to == NULL ? "NO-TO-LIST"
3574                                                   : shortenstring(e->e_to,
3575                                                                   MAXSHORTSTR),
3576                                  m->m_name);
3577                checkfd012(wbuf);
3578#endif /* XDEBUG */
3579
3580                errno = 0;
3581
3582                /*
3583                **  It was originally necessary to set macro 'g' to NULL
3584                **  because it previously pointed to an auto buffer.
3585                **  We don't do this any more, so this may be unnecessary.
3586                */
3587
3588                macdefine(&e->e_macro, A_PERM, 'g', (char *) NULL);
3589                e->e_to = NULL;
3590        }
3591        SM_END_TRY
3592        return rcode;
3593}
3594
3595/*
3596**  MARKFAILURE -- mark a failure on a specific address.
3597**
3598**      Parameters:
3599**              e -- the envelope we are sending.
3600**              q -- the address to mark.
3601**              mci -- mailer connection information.
3602**              rcode -- the code signifying the particular failure.
3603**              ovr -- override an existing code?
3604**
3605**      Returns:
3606**              none.
3607**
3608**      Side Effects:
3609**              marks the address (and possibly the envelope) with the
3610**                      failure so that an error will be returned or
3611**                      the message will be queued, as appropriate.
3612*/
3613
3614void
3615markfailure(e, q, mci, rcode, ovr)
3616        register ENVELOPE *e;
3617        register ADDRESS *q;
3618        register MCI *mci;
3619        int rcode;
3620        bool ovr;
3621{
3622        int save_errno = errno;
3623        char *status = NULL;
3624        char *rstatus = NULL;
3625
3626        switch (rcode)
3627        {
3628          case EX_OK:
3629                break;
3630
3631          case EX_TEMPFAIL:
3632          case EX_IOERR:
3633          case EX_OSERR:
3634                q->q_state = QS_QUEUEUP;
3635                break;
3636
3637          default:
3638                q->q_state = QS_BADADDR;
3639                break;
3640        }
3641
3642        /* find most specific error code possible */
3643        if (mci != NULL && mci->mci_status != NULL)
3644        {
3645                status = sm_rpool_strdup_x(e->e_rpool, mci->mci_status);
3646                if (mci->mci_rstatus != NULL)
3647                        rstatus = sm_rpool_strdup_x(e->e_rpool,
3648                                                    mci->mci_rstatus);
3649                else
3650                        rstatus = NULL;
3651        }
3652        else if (e->e_status != NULL)
3653        {
3654                status = e->e_status;
3655                rstatus = NULL;
3656        }
3657        else
3658        {
3659                switch (rcode)
3660                {
3661                  case EX_USAGE:
3662                        status = "5.5.4";
3663                        break;
3664
3665                  case EX_DATAERR:
3666                        status = "5.5.2";
3667                        break;
3668
3669                  case EX_NOUSER:
3670                        status = "5.1.1";
3671                        break;
3672
3673                  case EX_NOHOST:
3674                        status = "5.1.2";
3675                        break;
3676
3677                  case EX_NOINPUT:
3678                  case EX_CANTCREAT:
3679                  case EX_NOPERM:
3680                        status = "5.3.0";
3681                        break;
3682
3683                  case EX_UNAVAILABLE:
3684                  case EX_SOFTWARE:
3685                  case EX_OSFILE:
3686                  case EX_PROTOCOL:
3687                  case EX_CONFIG:
3688                        status = "5.5.0";
3689                        break;
3690
3691                  case EX_OSERR:
3692                  case EX_IOERR:
3693                        status = "4.5.0";
3694                        break;
3695
3696                  case EX_TEMPFAIL:
3697                        status = "4.2.0";
3698                        break;
3699                }
3700        }
3701
3702        /* new status? */
3703        if (status != NULL && *status != '\0' && (ovr || q->q_status == NULL ||
3704            *q->q_status == '\0' || *q->q_status < *status))
3705        {
3706                q->q_status = status;
3707                q->q_rstatus = rstatus;
3708        }
3709        if (rcode != EX_OK && q->q_rstatus == NULL &&
3710            q->q_mailer != NULL && q->q_mailer->m_diagtype != NULL &&
3711            sm_strcasecmp(q->q_mailer->m_diagtype, "X-UNIX") == 0)
3712        {
3713                char buf[16];
3714
3715                (void) sm_snprintf(buf, sizeof buf, "%d", rcode);
3716                q->q_rstatus = sm_rpool_strdup_x(e->e_rpool, buf);
3717        }
3718
3719        q->q_statdate = curtime();
3720        if (CurHostName != NULL && CurHostName[0] != '\0' &&
3721            mci != NULL && !bitset(M_LOCALMAILER, mci->mci_flags))
3722                q->q_statmta = sm_rpool_strdup_x(e->e_rpool, CurHostName);
3723
3724        /* restore errno */
3725        errno = save_errno;
3726}
3727/*
3728**  ENDMAILER -- Wait for mailer to terminate.
3729**
3730**      We should never get fatal errors (e.g., segmentation
3731**      violation), so we report those specially.  For other
3732**      errors, we choose a status message (into statmsg),
3733**      and if it represents an error, we print it.
3734**
3735**      Parameters:
3736**              mci -- the mailer connection info.
3737**              e -- the current envelope.
3738**              pv -- the parameter vector that invoked the mailer
3739**                      (for error messages).
3740**
3741**      Returns:
3742**              exit code of mailer.
3743**
3744**      Side Effects:
3745**              none.
3746*/
3747
3748static jmp_buf  EndWaitTimeout;
3749
3750static void
3751endwaittimeout()
3752{
3753        /*
3754        **  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
3755        **      ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
3756        **      DOING.
3757        */
3758
3759        errno = ETIMEDOUT;
3760        longjmp(EndWaitTimeout, 1);
3761}
3762
3763int
3764endmailer(mci, e, pv)
3765        register MCI *mci;
3766        register ENVELOPE *e;
3767        char **pv;
3768{
3769        int st;
3770        int save_errno = errno;
3771        char buf[MAXLINE];
3772        SM_EVENT *ev = NULL;
3773
3774
3775        mci_unlock_host(mci);
3776
3777        /* close output to mailer */
3778        if (mci->mci_out != NULL)
3779                (void) sm_io_close(mci->mci_out, SM_TIME_DEFAULT);
3780
3781        /* copy any remaining input to transcript */
3782        if (mci->mci_in != NULL && mci->mci_state != MCIS_ERROR &&
3783            e->e_xfp != NULL)
3784        {
3785                while (sfgets(buf, sizeof buf, mci->mci_in,
3786                              TimeOuts.to_quit, "Draining Input") != NULL)
3787                        (void) sm_io_fputs(e->e_xfp, SM_TIME_DEFAULT, buf);
3788        }
3789
3790#if SASL
3791        /* close SASL connection */
3792        if (bitset(MCIF_AUTHACT, mci->mci_flags))
3793        {
3794                sasl_dispose(&mci->mci_conn);
3795                mci->mci_flags &= ~MCIF_AUTHACT;
3796        }
3797#endif /* SASL */
3798
3799#if STARTTLS
3800        /* shutdown TLS */
3801        (void) endtlsclt(mci);
3802#endif /* STARTTLS */
3803
3804        /* now close the input */
3805        if (mci->mci_in != NULL)
3806                (void) sm_io_close(mci->mci_in, SM_TIME_DEFAULT);
3807        mci->mci_in = mci->mci_out = NULL;
3808        mci->mci_state = MCIS_CLOSED;
3809
3810        errno = save_errno;
3811
3812        /* in the IPC case there is nothing to wait for */
3813        if (mci->mci_pid == 0)
3814                return EX_OK;
3815
3816        /* put a timeout around the wait */
3817        if (mci->mci_mailer->m_wait > 0)
3818        {
3819                if (setjmp(EndWaitTimeout) == 0)
3820                        ev = sm_setevent(mci->mci_mailer->m_wait,
3821                                         endwaittimeout, 0);
3822                else
3823                {
3824                        syserr("endmailer %s: wait timeout (%ld)",
3825                               mci->mci_mailer->m_name,
3826                               (long) mci->mci_mailer->m_wait);
3827                        return EX_TEMPFAIL;
3828                }
3829        }
3830
3831        /* wait for the mailer process, collect status */
3832        st = waitfor(mci->mci_pid);
3833        save_errno = errno;
3834        if (ev != NULL)
3835                sm_clrevent(ev);
3836        errno = save_errno;
3837
3838        if (st == -1)
3839        {
3840                syserr("endmailer %s: wait", mci->mci_mailer->m_name);
3841                return EX_SOFTWARE;
3842        }
3843
3844        if (WIFEXITED(st))
3845        {
3846                /* normal death -- return status */
3847                return (WEXITSTATUS(st));
3848        }
3849
3850        /* it died a horrid death */
3851        syserr("451 4.3.0 mailer %s died with signal %d%s",
3852                mci->mci_mailer->m_name, WTERMSIG(st),
3853                WCOREDUMP(st) ? " (core dumped)" :
3854                (WIFSTOPPED(st) ? " (stopped)" : ""));
3855
3856        /* log the arguments */
3857        if (pv != NULL && e->e_xfp != NULL)
3858        {
3859                register char **av;
3860
3861                (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, "Arguments:");
3862                for (av = pv; *av != NULL; av++)
3863                        (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, " %s",
3864                                             *av);
3865                (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, "\n");
3866        }
3867
3868        ExitStat = EX_TEMPFAIL;
3869        return EX_TEMPFAIL;
3870}
3871/*
3872**  GIVERESPONSE -- Interpret an error response from a mailer
3873**
3874**      Parameters:
3875**              status -- the status code from the mailer (high byte
3876**                      only; core dumps must have been taken care of
3877**                      already).
3878**              dsn -- the DSN associated with the address, if any.
3879**              m -- the mailer info for this mailer.
3880**              mci -- the mailer connection info -- can be NULL if the
3881**                      response is given before the connection is made.
3882**              ctladdr -- the controlling address for the recipient
3883**                      address(es).
3884**              xstart -- the transaction start time, for computing
3885**                      transaction delays.
3886**              e -- the current envelope.
3887**              to -- the current recipient (NULL if none).
3888**
3889**      Returns:
3890**              none.
3891**
3892**      Side Effects:
3893**              Errors may be incremented.
3894**              ExitStat may be set.
3895*/
3896
3897void
3898giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
3899        int status;
3900        char *dsn;
3901        register MAILER *m;
3902        register MCI *mci;
3903        ADDRESS *ctladdr;
3904        time_t xstart;
3905        ENVELOPE *e;
3906        ADDRESS *to;
3907{
3908        register const char *statmsg;
3909        int errnum = errno;
3910        int off = 4;
3911        bool usestat = false;
3912        char dsnbuf[ENHSCLEN];
3913        char buf[MAXLINE];
3914        char *exmsg;
3915
3916        if (e == NULL)
3917                syserr("giveresponse: null envelope");
3918
3919        /*
3920        **  Compute status message from code.
3921        */
3922
3923        exmsg = sm_sysexmsg(status);
3924        if (status == 0)
3925        {
3926                statmsg = "250 2.0.0 Sent";
3927                if (e->e_statmsg != NULL)
3928                {
3929                        (void) sm_snprintf(buf, sizeof buf, "%s (%s)",
3930                                           statmsg,
3931                                           shortenstring(e->e_statmsg, 403));
3932                        statmsg = buf;
3933                }
3934        }
3935        else if (exmsg == NULL)
3936        {
3937                (void) sm_snprintf(buf, sizeof buf,
3938                                   "554 5.3.0 unknown mailer error %d",
3939                                   status);
3940                status = EX_UNAVAILABLE;
3941                statmsg = buf;
3942                usestat = true;
3943        }
3944        else if (status == EX_TEMPFAIL)
3945        {
3946                char *bp = buf;
3947
3948                (void) sm_strlcpy(bp, exmsg + 1, SPACELEFT(buf, bp));
3949                bp += strlen(bp);
3950#if NAMED_BIND
3951                if (h_errno == TRY_AGAIN)
3952                        statmsg = sm_errstring(h_errno + E_DNSBASE);
3953                else
3954#endif /* NAMED_BIND */
3955                {
3956                        if (errnum != 0)
3957                                statmsg = sm_errstring(errnum);
3958                        else
3959                                statmsg = SmtpError;
3960                }
3961                if (statmsg != NULL && statmsg[0] != '\0')
3962                {
3963                        switch (errnum)
3964                        {
3965#ifdef ENETDOWN
3966                          case ENETDOWN:        /* Network is down */
3967#endif /* ENETDOWN */
3968#ifdef ENETUNREACH
3969                          case ENETUNREACH:     /* Network is unreachable */
3970#endif /* ENETUNREACH */
3971#ifdef ENETRESET
3972                          case ENETRESET:       /* Network dropped connection on reset */
3973#endif /* ENETRESET */
3974#ifdef ECONNABORTED
3975                          case ECONNABORTED:    /* Software caused connection abort */
3976#endif /* ECONNABORTED */
3977#ifdef EHOSTDOWN
3978                          case EHOSTDOWN:       /* Host is down */
3979#endif /* EHOSTDOWN */
3980#ifdef EHOSTUNREACH
3981                          case EHOSTUNREACH:    /* No route to host */
3982#endif /* EHOSTUNREACH */
3983                                if (mci->mci_host != NULL)
3984                                {
3985                                        (void) sm_strlcpyn(bp,
3986                                                           SPACELEFT(buf, bp),
3987                                                           2, ": ",
3988                                                           mci->mci_host);
3989                                        bp += strlen(bp);
3990                                }
3991                                break;
3992                        }
3993                        (void) sm_strlcpyn(bp, SPACELEFT(buf, bp), 2, ": ",
3994                                           statmsg);
3995                        usestat = true;
3996                }
3997                statmsg = buf;
3998        }
3999#if NAMED_BIND
4000        else if (status == EX_NOHOST && h_errno != 0)
4001        {
4002                statmsg = sm_errstring(h_errno + E_DNSBASE);
4003                (void) sm_snprintf(buf, sizeof buf, "%s (%s)", exmsg + 1,
4004                                   statmsg);
4005                statmsg = buf;
4006                usestat = true;
4007        }
4008#endif /* NAMED_BIND */
4009        else
4010        {
4011                statmsg = exmsg;
4012                if (*statmsg++ == ':' && errnum != 0)
4013                {
4014                        (void) sm_snprintf(buf, sizeof buf, "%s: %s", statmsg,
4015                                           sm_errstring(errnum));
4016                        statmsg = buf;
4017                        usestat = true;
4018                }
4019                else if (bitnset(M_LMTP, m->m_flags) && e->e_statmsg != NULL)
4020                {
4021                        (void) sm_snprintf(buf, sizeof buf, "%s (%s)", statmsg,
4022                                           shortenstring(e->e_statmsg, 403));
4023                        statmsg = buf;
4024                        usestat = true;
4025                }
4026        }
4027
4028        /*
4029        **  Print the message as appropriate
4030        */
4031
4032        if (status == EX_OK || status == EX_TEMPFAIL)
4033        {
4034                extern char MsgBuf[];
4035
4036                if ((off = isenhsc(statmsg + 4, ' ')) > 0)
4037                {
4038                        if (dsn == NULL)
4039                        {
4040                                (void) sm_snprintf(dsnbuf, sizeof dsnbuf,
4041                                                   "%.*s", off, statmsg + 4);
4042                                dsn = dsnbuf;
4043                        }
4044                        off += 5;
4045                }
4046                else
4047                {
4048                        off = 4;
4049                }
4050                message("%s", statmsg + off);
4051                if (status == EX_TEMPFAIL && e->e_xfp != NULL)
4052                        (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, "%s\n",
4053                                             &MsgBuf[4]);
4054        }
4055        else
4056        {
4057                char mbuf[ENHSCLEN + 4];
4058
4059                Errors++;
4060                if ((off = isenhsc(statmsg + 4, ' ')) > 0 &&
4061                    off < sizeof mbuf - 4)
4062                {
4063                        if (dsn == NULL)
4064                        {
4065                                (void) sm_snprintf(dsnbuf, sizeof dsnbuf,
4066                                                   "%.*s", off, statmsg + 4);
4067                                dsn = dsnbuf;
4068                        }
4069                        off += 5;
4070
4071                        /* copy only part of statmsg to mbuf */
4072                        (void) sm_strlcpy(mbuf, statmsg, off);
4073                        (void) sm_strlcat(mbuf, " %s", sizeof mbuf);
4074                }
4075                else
4076                {
4077                        dsnbuf[0] = '\0';
4078                        (void) sm_snprintf(mbuf, sizeof mbuf, "%.3s %%s",
4079                                           statmsg);
4080                        off = 4;
4081                }
4082                usrerr(mbuf, &statmsg[off]);
4083        }
4084
4085        /*
4086        **  Final cleanup.
4087        **      Log a record of the transaction.  Compute the new
4088        **      ExitStat -- if we already had an error, stick with
4089        **      that.
4090        */
4091
4092        if (OpMode != MD_VERIFY && !bitset(EF_VRFYONLY, e->e_flags) &&
4093            LogLevel > ((status == EX_TEMPFAIL) ? 8 : (status == EX_OK) ? 7 : 6))
4094                logdelivery(m, mci, dsn, statmsg + off, ctladdr, xstart, e);
4095
4096        if (tTd(11, 2))
4097                sm_dprintf("giveresponse: status=%d, dsn=%s, e->e_message=%s, errnum=%d\n",
4098                           status,
4099                           dsn == NULL ? "<NULL>" : dsn,
4100                           e->e_message == NULL ? "<NULL>" : e->e_message,
4101                           errnum);
4102
4103        if (status != EX_TEMPFAIL)
4104                setstat(status);
4105        if (status != EX_OK && (status != EX_TEMPFAIL || e->e_message == NULL))
4106                e->e_message = sm_rpool_strdup_x(e->e_rpool, statmsg + off);
4107        if (status != EX_OK && to != NULL && to->q_message == NULL)
4108        {
4109                if (!usestat && e->e_message != NULL)
4110                        to->q_message = sm_rpool_strdup_x(e->e_rpool,
4111                                                          e->e_message);
4112                else
4113                        to->q_message = sm_rpool_strdup_x(e->e_rpool,
4114                                                          statmsg + off);
4115        }
4116        errno = 0;
4117        SM_SET_H_ERRNO(0);
4118}
4119/*
4120**  LOGDELIVERY -- log the delivery in the system log
4121**
4122**      Care is taken to avoid logging lines that are too long, because
4123**      some versions of syslog have an unfortunate proclivity for core
4124**      dumping.  This is a hack, to be sure, that is at best empirical.
4125**
4126**      Parameters:
4127**              m -- the mailer info.  Can be NULL for initial queue.
4128**              mci -- the mailer connection info -- can be NULL if the
4129**                      log is occurring when no connection is active.
4130**              dsn -- the DSN attached to the status.
4131**              status -- the message to print for the status.
4132**              ctladdr -- the controlling address for the to list.
4133**              xstart -- the transaction start time, used for
4134**                      computing transaction delay.
4135**              e -- the current envelope.
4136**
4137**      Returns:
4138**              none
4139**
4140**      Side Effects:
4141**              none
4142*/
4143
4144void
4145logdelivery(m, mci, dsn, status, ctladdr, xstart, e)
4146        MAILER *m;
4147        register MCI *mci;
4148        char *dsn;
4149        const char *status;
4150        ADDRESS *ctladdr;
4151        time_t xstart;
4152        register ENVELOPE *e;
4153{
4154        register char *bp;
4155        register char *p;
4156        int l;
4157        time_t now = curtime();
4158        char buf[1024];
4159
4160#if (SYSLOG_BUFSIZE) >= 256
4161        /* ctladdr: max 106 bytes */
4162        bp = buf;
4163        if (ctladdr != NULL)
4164        {
4165                (void) sm_strlcpyn(bp, SPACELEFT(buf, bp), 2, ", ctladdr=",
4166                                   shortenstring(ctladdr->q_paddr, 83));
4167                bp += strlen(bp);
4168                if (bitset(QGOODUID, ctladdr->q_flags))
4169                {
4170                        (void) sm_snprintf(bp, SPACELEFT(buf, bp), " (%d/%d)",
4171                                           (int) ctladdr->q_uid,
4172                                           (int) ctladdr->q_gid);
4173                        bp += strlen(bp);
4174                }
4175        }
4176
4177        /* delay & xdelay: max 41 bytes */
4178        (void) sm_strlcpyn(bp, SPACELEFT(buf, bp), 2, ", delay=",
4179                           pintvl(now - e->e_ctime, true));
4180        bp += strlen(bp);
4181
4182        if (xstart != (time_t) 0)
4183        {
4184                (void) sm_strlcpyn(bp, SPACELEFT(buf, bp), 2, ", xdelay=",
4185                                   pintvl(now - xstart, true));
4186                bp += strlen(bp);
4187        }
4188
4189        /* mailer: assume about 19 bytes (max 10 byte mailer name) */
4190        if (m != NULL)
4191        {
4192                (void) sm_strlcpyn(bp, SPACELEFT(buf, bp), 2, ", mailer=",
4193                                   m->m_name);
4194                bp += strlen(bp);
4195        }
4196
4197        /* pri: changes with each delivery attempt */
4198        (void) sm_snprintf(bp, SPACELEFT(buf, bp), ", pri=%ld",
4199                e->e_msgpriority);
4200        bp += strlen(bp);
4201
4202        /* relay: max 66 bytes for IPv4 addresses */
4203        if (mci != NULL && mci->mci_host != NULL)
4204        {
4205                extern SOCKADDR CurHostAddr;
4206
4207                (void) sm_strlcpyn(bp, SPACELEFT(buf, bp), 2, ", relay=",
4208                                   shortenstring(mci->mci_host, 40));
4209                bp += strlen(bp);
4210
4211                if (CurHostAddr.sa.sa_family != 0)
4212                {
4213                        (void) sm_snprintf(bp, SPACELEFT(buf, bp), " [%s]",
4214                                           anynet_ntoa(&CurHostAddr));
4215                }
4216        }
4217#if _FFR_QUARANTINE
4218        else if (strcmp(status, "quarantined") == 0)
4219        {
4220                if (e->e_quarmsg != NULL)
4221                        (void) sm_snprintf(bp, SPACELEFT(buf, bp),
4222                                           ", quarantine=%s",
4223                                           shortenstring(e->e_quarmsg, 40));
4224        }
4225#endif /* _FFR_QUARANTINE */
4226        else if (strcmp(status, "queued") != 0)
4227        {
4228                p = macvalue('h', e);
4229                if (p != NULL && p[0] != '\0')
4230                {
4231                        (void) sm_snprintf(bp, SPACELEFT(buf, bp),
4232                                           ", relay=%s", shortenstring(p, 40));
4233                }
4234        }
4235        bp += strlen(bp);
4236
4237        /* dsn */
4238        if (dsn != NULL && *dsn != '\0')
4239        {
4240                (void) sm_strlcpyn(bp, SPACELEFT(buf, bp), 2, ", dsn=",
4241                                   shortenstring(dsn, ENHSCLEN));
4242                bp += strlen(bp);
4243        }
4244
4245# define STATLEN                (((SYSLOG_BUFSIZE) - 100) / 4)
4246# if (STATLEN) < 63
4247#  undef STATLEN
4248#  define STATLEN       63
4249# endif /* (STATLEN) < 63 */
4250# if (STATLEN) > 203
4251#  undef STATLEN
4252#  define STATLEN       203
4253# endif /* (STATLEN) > 203 */
4254
4255        /* stat: max 210 bytes */
4256        if ((bp - buf) > (sizeof buf - ((STATLEN) + 20)))
4257        {
4258                /* desperation move -- truncate data */
4259                bp = buf + sizeof buf - ((STATLEN) + 17);
4260                (void) sm_strlcpy(bp, "...", SPACELEFT(buf, bp));
4261                bp += 3;
4262        }
4263
4264        (void) sm_strlcpy(bp, ", stat=", SPACELEFT(buf, bp));
4265        bp += strlen(bp);
4266
4267        (void) sm_strlcpy(bp, shortenstring(status, STATLEN),
4268                          SPACELEFT(buf, bp));
4269
4270        /* id, to: max 13 + TOBUFSIZE bytes */
4271        l = SYSLOG_BUFSIZE - 100 - strlen(buf);
4272        if (l < 0)
4273                l = 0;
4274        p = e->e_to == NULL ? "NO-TO-LIST" : e->e_to;
4275        while (strlen(p) >= l)
4276        {
4277                register char *q;
4278
4279                for (q = p + l; q > p; q--)
4280                {
4281                        if (*q == ',')
4282                                break;
4283                }
4284                if (p == q)
4285                        break;
4286                sm_syslog(LOG_INFO, e->e_id, "to=%.*s [more]%s",
4287                          (int) (++q - p), p, buf);
4288                p = q;
4289        }
4290        sm_syslog(LOG_INFO, e->e_id, "to=%.*s%s", l, p, buf);
4291
4292#else /* (SYSLOG_BUFSIZE) >= 256 */
4293
4294        l = SYSLOG_BUFSIZE - 85;
4295        if (l < 0)
4296                l = 0;
4297        p = e->e_to == NULL ? "NO-TO-LIST" : e->e_to;
4298        while (strlen(p) >= l)
4299        {
4300                register char *q;
4301
4302                for (q = p + l; q > p; q--)
4303                {
4304                        if (*q == ',')
4305                                break;
4306                }
4307                if (p == q)
4308                        break;
4309
4310                sm_syslog(LOG_INFO, e->e_id, "to=%.*s [more]",
4311                          (int) (++q - p), p);
4312                p = q;
4313        }
4314        sm_syslog(LOG_INFO, e->e_id, "to=%.*s", l, p);
4315
4316        if (ctladdr != NULL)
4317        {
4318                bp = buf;
4319                (void) sm_strlcpyn(bp, SPACELEFT(buf, bp), 2, "ctladdr=",
4320                                   shortenstring(ctladdr->q_paddr, 83));
4321                bp += strlen(bp);
4322                if (bitset(QGOODUID, ctladdr->q_flags))
4323                {
4324                        (void) sm_snprintf(bp, SPACELEFT(buf, bp), " (%d/%d)",
4325                                           ctladdr->q_uid, ctladdr->q_gid);
4326                        bp += strlen(bp);
4327                }
4328                sm_syslog(LOG_INFO, e->e_id, "%s", buf);
4329        }
4330        bp = buf;
4331        (void) sm_strlcpyn(bp, SPACELEFT(buf, bp), 2, "delay=",
4332                           pintvl(now - e->e_ctime, true));
4333        bp += strlen(bp);
4334        if (xstart != (time_t) 0)
4335        {
4336                (void) sm_strlcpyn(bp, SPACELEFT(buf, bp), 2, ", xdelay=",
4337                                   pintvl(now - xstart, true));
4338                bp += strlen(bp);
4339        }
4340
4341        if (m != NULL)
4342        {
4343                (void) sm_strlcpyn(bp, SPACELEFT(buf, bp), 2, ", mailer=",
4344                                   m->m_name);
4345                bp += strlen(bp);
4346        }
4347        sm_syslog(LOG_INFO, e->e_id, "%.1000s", buf);
4348
4349        buf[0] = '\0';
4350        bp = buf;
4351        if (mci != NULL && mci->mci_host != NULL)
4352        {
4353                extern SOCKADDR CurHostAddr;
4354
4355                (void) sm_snprintf(bp, SPACELEFT(buf, bp), "relay=%.100s",
4356                                   mci->mci_host);
4357                bp += strlen(bp);
4358
4359                if (CurHostAddr.sa.sa_family != 0)
4360                        (void) sm_snprintf(bp, SPACELEFT(buf, bp),
4361                                           " [%.100s]",
4362                                           anynet_ntoa(&CurHostAddr));
4363        }
4364#if _FFR_QUARANTINE
4365        else if (strcmp(status, "quarantined") == 0)
4366        {
4367                if (e->e_quarmsg != NULL)
4368                        (void) sm_snprintf(bp, SPACELEFT(buf, bp),
4369                                           ", quarantine=%.100s",
4370                                           e->e_quarmsg);
4371        }
4372#endif /* _FFR_QUARANTINE */
4373        else if (strcmp(status, "queued") != 0)
4374        {
4375                p = macvalue('h', e);
4376                if (p != NULL && p[0] != '\0')
4377                        (void) sm_snprintf(buf, sizeof buf, "relay=%.100s", p);
4378        }
4379        if (buf[0] != '\0')
4380                sm_syslog(LOG_INFO, e->e_id, "%.1000s", buf);
4381
4382        sm_syslog(LOG_INFO, e->e_id, "stat=%s", shortenstring(status, 63));
4383#endif /* (SYSLOG_BUFSIZE) >= 256 */
4384}
4385/*
4386**  PUTFROMLINE -- output a UNIX-style from line (or whatever)
4387**
4388**      This can be made an arbitrary message separator by changing $l
4389**
4390**      One of the ugliest hacks seen by human eyes is contained herein:
4391**      UUCP wants those stupid "remote from <host>" lines.  Why oh why
4392**      does a well-meaning programmer such as myself have to deal with
4393**      this kind of antique garbage????
4394**
4395**      Parameters:
4396**              mci -- the connection information.
4397**              e -- the envelope.
4398**
4399**      Returns:
4400**              true iff line was written successfully
4401**
4402**      Side Effects:
4403**              outputs some text to fp.
4404*/
4405
4406bool
4407putfromline(mci, e)
4408        register MCI *mci;
4409        ENVELOPE *e;
4410{
4411        char *template = UnixFromLine;
4412        char buf[MAXLINE];
4413        char xbuf[MAXLINE];
4414
4415        if (bitnset(M_NHDR, mci->mci_mailer->m_flags))
4416                return true;
4417
4418        mci->mci_flags |= MCIF_INHEADER;
4419
4420        if (bitnset(M_UGLYUUCP, mci->mci_mailer->m_flags))
4421        {
4422                char *bang;
4423
4424                expand("\201g", buf, sizeof buf, e);
4425                bang = strchr(buf, '!');
4426                if (bang == NULL)
4427                {
4428                        char *at;
4429                        char hname[MAXNAME];
4430
4431                        /*
4432                        **  If we can construct a UUCP path, do so
4433                        */
4434
4435                        at = strrchr(buf, '@');
4436                        if (at == NULL)
4437                        {
4438                                expand("\201k", hname, sizeof hname, e);
4439                                at = hname;
4440                        }
4441                        else
4442                                *at++ = '\0';
4443                        (void) sm_snprintf(xbuf, sizeof xbuf,
4444                                           "From %.800s  \201d remote from %.100s\n",
4445                                           buf, at);
4446                }
4447                else
4448                {
4449                        *bang++ = '\0';
4450                        (void) sm_snprintf(xbuf, sizeof xbuf,
4451                                           "From %.800s  \201d remote from %.100s\n",
4452                                           bang, buf);
4453                        template = xbuf;
4454                }
4455        }
4456        expand(template, buf, sizeof buf, e);
4457        return putxline(buf, strlen(buf), mci, PXLF_HEADER);
4458}
4459
4460/*
4461**  PUTBODY -- put the body of a message.
4462**
4463**      Parameters:
4464**              mci -- the connection information.
4465**              e -- the envelope to put out.
4466**              separator -- if non-NULL, a message separator that must
4467**                      not be permitted in the resulting message.
4468**
4469**      Returns:
4470**              true iff message was written successfully
4471**
4472**      Side Effects:
4473**              The message is written onto fp.
4474*/
4475
4476/* values for output state variable */
4477#define OS_HEAD         0       /* at beginning of line */
4478#define OS_CR           1       /* read a carriage return */
4479#define OS_INLINE       2       /* putting rest of line */
4480
4481bool
4482putbody(mci, e, separator)
4483        register MCI *mci;
4484        register ENVELOPE *e;
4485        char *separator;
4486{
4487        bool dead = false;
4488        bool ioerr = false;
4489        int save_errno;
4490        char buf[MAXLINE];
4491#if MIME8TO7
4492        char *boundaries[MAXMIMENESTING + 1];
4493#endif /* MIME8TO7 */
4494
4495        /*
4496        **  Output the body of the message
4497        */
4498
4499        if (e->e_dfp == NULL && bitset(EF_HAS_DF, e->e_flags))
4500        {
4501                char *df = queuename(e, DATAFL_LETTER);
4502
4503                e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, df,
4504                                      SM_IO_RDONLY, NULL);
4505                if (e->e_dfp == NULL)
4506                {
4507                        char *msg = "!putbody: Cannot open %s for %s from %s";
4508
4509                        if (errno == ENOENT)
4510                                msg++;
4511                        syserr(msg, df, e->e_to, e->e_from.q_paddr);
4512                }
4513
4514        }
4515        if (e->e_dfp == NULL)
4516        {
4517                if (bitset(MCIF_INHEADER, mci->mci_flags))
4518                {
4519                        if (!putline("", mci))
4520                                goto writeerr;
4521                        mci->mci_flags &= ~MCIF_INHEADER;
4522                }
4523                if (!putline("<<< No Message Collected >>>", mci))
4524                        goto writeerr;
4525                goto endofmessage;
4526        }
4527
4528        if (e->e_dfino == (ino_t) 0)
4529        {
4530                struct stat stbuf;
4531
4532                if (fstat(sm_io_getinfo(e->e_dfp, SM_IO_WHAT_FD, NULL), &stbuf)
4533                    < 0)
4534                        e->e_dfino = -1;
4535                else
4536                {
4537                        e->e_dfdev = stbuf.st_dev;
4538                        e->e_dfino = stbuf.st_ino;
4539                }
4540        }
4541
4542        /* paranoia: the data file should always be in a rewound state */
4543        (void) bfrewind(e->e_dfp);
4544
4545#if MIME8TO7
4546        if (bitset(MCIF_CVT8TO7, mci->mci_flags))
4547        {
4548                /*
4549                **  Do 8 to 7 bit MIME conversion.
4550                */
4551
4552                /* make sure it looks like a MIME message */
4553                if (hvalue("MIME-Version", e->e_header) == NULL &&
4554                    !putline("MIME-Version: 1.0", mci))
4555                        goto writeerr;
4556
4557                if (hvalue("Content-Type", e->e_header) == NULL)
4558                {
4559                        (void) sm_snprintf(buf, sizeof buf,
4560                                           "Content-Type: text/plain; charset=%s",
4561                                           defcharset(e));
4562                        if (!putline(buf, mci))
4563                                goto writeerr;
4564                }
4565
4566                /* now do the hard work */
4567                boundaries[0] = NULL;
4568                mci->mci_flags |= MCIF_INHEADER;
4569                if (mime8to7(mci, e->e_header, e, boundaries, M87F_OUTER) ==
4570                                                                SM_IO_EOF)
4571                        goto writeerr;
4572        }
4573# if MIME7TO8
4574        else if (bitset(MCIF_CVT7TO8, mci->mci_flags))
4575        {
4576                if (!mime7to8(mci, e->e_header, e))
4577                        goto writeerr;
4578        }
4579# endif /* MIME7TO8 */
4580        else if (MaxMimeHeaderLength > 0 || MaxMimeFieldLength > 0)
4581        {
4582                bool oldsuprerrs = SuprErrs;
4583
4584                /* Use mime8to7 to check multipart for MIME header overflows */
4585                boundaries[0] = NULL;
4586                mci->mci_flags |= MCIF_INHEADER;
4587
4588                /*
4589                **  If EF_DONT_MIME is set, we have a broken MIME message
4590                **  and don't want to generate a new bounce message whose
4591                **  body propagates the broken MIME.  We can't just not call
4592                **  mime8to7() as is done above since we need the security
4593                **  checks.  The best we can do is suppress the errors.
4594                */
4595
4596                if (bitset(EF_DONT_MIME, e->e_flags))
4597                        SuprErrs = true;
4598
4599                if (mime8to7(mci, e->e_header, e, boundaries,
4600                                M87F_OUTER|M87F_NO8TO7) == SM_IO_EOF)
4601                        goto writeerr;
4602
4603                /* restore SuprErrs */
4604                SuprErrs = oldsuprerrs;
4605        }
4606        else
4607#endif /* MIME8TO7 */
4608        {
4609                int ostate;
4610                register char *bp;
4611                register char *pbp;
4612                register int c;
4613                register char *xp;
4614                int padc;
4615                char *buflim;
4616                int pos = 0;
4617                char peekbuf[12];
4618
4619                if (bitset(MCIF_INHEADER, mci->mci_flags))
4620                {
4621                        if (!putline("", mci))
4622                                goto writeerr;
4623                        mci->mci_flags &= ~MCIF_INHEADER;
4624                }
4625
4626                /* determine end of buffer; allow for short mailer lines */
4627                buflim = &buf[sizeof buf - 1];
4628                if (mci->mci_mailer->m_linelimit > 0 &&
4629                    mci->mci_mailer->m_linelimit < sizeof buf - 1)
4630                        buflim = &buf[mci->mci_mailer->m_linelimit - 1];
4631
4632                /* copy temp file to output with mapping */
4633                ostate = OS_HEAD;
4634                bp = buf;
4635                pbp = peekbuf;
4636                while (!sm_io_error(mci->mci_out) && !dead)
4637                {
4638                        if (pbp > peekbuf)
4639                                c = *--pbp;
4640                        else if ((c = sm_io_getc(e->e_dfp, SM_TIME_DEFAULT))
4641                                 == SM_IO_EOF)
4642                                break;
4643                        if (bitset(MCIF_7BIT, mci->mci_flags))
4644                                c &= 0x7f;
4645                        switch (ostate)
4646                        {
4647                          case OS_HEAD:
4648                                if (c == '\0' &&
4649                                    bitnset(M_NONULLS,
4650                                            mci->mci_mailer->m_flags))
4651                                        break;
4652                                if (c != '\r' && c != '\n' && bp < buflim)
4653                                {
4654                                        *bp++ = c;
4655                                        break;
4656                                }
4657
4658                                /* check beginning of line for special cases */
4659                                *bp = '\0';
4660                                pos = 0;
4661                                padc = SM_IO_EOF;
4662                                if (buf[0] == 'F' &&
4663                                    bitnset(M_ESCFROM, mci->mci_mailer->m_flags)
4664                                    && strncmp(buf, "From ", 5) == 0)
4665                                {
4666                                        padc = '>';
4667                                }
4668                                if (buf[0] == '-' && buf[1] == '-' &&
4669                                    separator != NULL)
4670                                {
4671                                        /* possible separator */
4672                                        int sl = strlen(separator);
4673
4674                                        if (strncmp(&buf[2], separator, sl)
4675                                            == 0)
4676                                                padc = ' ';
4677                                }
4678                                if (buf[0] == '.' &&
4679                                    bitnset(M_XDOT, mci->mci_mailer->m_flags))
4680                                {
4681                                        padc = '.';
4682                                }
4683
4684                                /* now copy out saved line */
4685                                if (TrafficLogFile != NULL)
4686                                {
4687                                        (void) sm_io_fprintf(TrafficLogFile,
4688                                                             SM_TIME_DEFAULT,
4689                                                             "%05d >>> ",
4690                                                             (int) CurrentPid);
4691                                        if (padc != SM_IO_EOF)
4692                                                (void) sm_io_putc(TrafficLogFile,
4693                                                                  SM_TIME_DEFAULT,
4694                                                                  padc);
4695                                        for (xp = buf; xp < bp; xp++)
4696                                                (void) sm_io_putc(TrafficLogFile,
4697                                                                  SM_TIME_DEFAULT,
4698                                                                  (unsigned char) *xp);
4699                                        if (c == '\n')
4700                                                (void) sm_io_fputs(TrafficLogFile,
4701                                                                   SM_TIME_DEFAULT,
4702                                                                   mci->mci_mailer->m_eol);
4703                                }
4704                                if (padc != SM_IO_EOF)
4705                                {
4706                                        if (sm_io_putc(mci->mci_out,
4707                                                       SM_TIME_DEFAULT, padc)
4708                                            == SM_IO_EOF)
4709                                        {
4710                                                dead = true;
4711                                                continue;
4712                                        }
4713                                        pos++;
4714                                }
4715                                for (xp = buf; xp < bp; xp++)
4716                                {
4717                                        if (sm_io_putc(mci->mci_out,
4718                                                       SM_TIME_DEFAULT,
4719                                                       (unsigned char) *xp)
4720                                            == SM_IO_EOF)
4721                                        {
4722                                                dead = true;
4723                                                break;
4724                                        }
4725                                }
4726                                if (dead)
4727                                        continue;
4728                                if (c == '\n')
4729                                {
4730                                        if (sm_io_fputs(mci->mci_out,
4731                                                        SM_TIME_DEFAULT,
4732                                                        mci->mci_mailer->m_eol)
4733                                                        == SM_IO_EOF)
4734                                                break;
4735                                        pos = 0;
4736                                }
4737                                else
4738                                {
4739                                        pos += bp - buf;
4740                                        if (c != '\r')
4741                                        {
4742                                                SM_ASSERT(pbp < peekbuf +
4743                                                                sizeof(peekbuf));
4744                                                *pbp++ = c;
4745                                        }
4746                                }
4747
4748                                bp = buf;
4749
4750                                /* determine next state */
4751                                if (c == '\n')
4752                                        ostate = OS_HEAD;
4753                                else if (c == '\r')
4754                                        ostate = OS_CR;
4755                                else
4756                                        ostate = OS_INLINE;
4757                                continue;
4758
4759                          case OS_CR:
4760                                if (c == '\n')
4761                                {
4762                                        /* got CRLF */
4763                                        if (sm_io_fputs(mci->mci_out,
4764                                                        SM_TIME_DEFAULT,
4765                                                        mci->mci_mailer->m_eol)
4766                                                        == SM_IO_EOF)
4767                                                continue;
4768
4769                                        if (TrafficLogFile != NULL)
4770                                        {
4771                                                (void) sm_io_fputs(TrafficLogFile,
4772                                                                   SM_TIME_DEFAULT,
4773                                                                   mci->mci_mailer->m_eol);
4774                                        }
4775                                        ostate = OS_HEAD;
4776                                        continue;
4777                                }
4778
4779                                /* had a naked carriage return */
4780                                SM_ASSERT(pbp < peekbuf + sizeof(peekbuf));
4781                                *pbp++ = c;
4782                                c = '\r';
4783                                ostate = OS_INLINE;
4784                                goto putch;
4785
4786                          case OS_INLINE:
4787                                if (c == '\r')
4788                                {
4789                                        ostate = OS_CR;
4790                                        continue;
4791                                }
4792                                if (c == '\0' &&
4793                                    bitnset(M_NONULLS,
4794                                            mci->mci_mailer->m_flags))
4795                                        break;
4796putch:
4797                                if (mci->mci_mailer->m_linelimit > 0 &&
4798                                    pos >= mci->mci_mailer->m_linelimit - 1 &&
4799                                    c != '\n')
4800                                {
4801                                        int d;
4802
4803                                        /* check next character for EOL */
4804                                        if (pbp > peekbuf)
4805                                                d = *(pbp - 1);
4806                                        else if ((d = sm_io_getc(e->e_dfp,
4807                                                                 SM_TIME_DEFAULT))
4808                                                 != SM_IO_EOF)
4809                                        {
4810                                                SM_ASSERT(pbp < peekbuf +
4811                                                                sizeof(peekbuf));
4812                                                *pbp++ = d;
4813                                        }
4814
4815                                        if (d == '\n' || d == SM_IO_EOF)
4816                                        {
4817                                                if (TrafficLogFile != NULL)
4818                                                        (void) sm_io_putc(TrafficLogFile,
4819                                                                          SM_TIME_DEFAULT,
4820                                                                          (unsigned char) c);
4821                                                if (sm_io_putc(mci->mci_out,
4822                                                               SM_TIME_DEFAULT,
4823                                                               (unsigned char) c)
4824                                                               == SM_IO_EOF)
4825                                                {
4826                                                        dead = true;
4827                                                        continue;
4828                                                }
4829                                                pos++;
4830                                                continue;
4831                                        }
4832
4833                                        if (sm_io_putc(mci->mci_out,
4834                                                       SM_TIME_DEFAULT, '!')
4835                                            == SM_IO_EOF ||
4836                                            sm_io_fputs(mci->mci_out,
4837                                                        SM_TIME_DEFAULT,
4838                                                        mci->mci_mailer->m_eol)
4839                                            == SM_IO_EOF)
4840                                        {
4841                                                dead = true;
4842                                                continue;
4843                                        }
4844
4845                                        if (TrafficLogFile != NULL)
4846                                        {
4847                                                (void) sm_io_fprintf(TrafficLogFile,
4848                                                                     SM_TIME_DEFAULT,
4849                                                                     "!%s",
4850                                                                     mci->mci_mailer->m_eol);
4851                                        }
4852                                        ostate = OS_HEAD;
4853                                        SM_ASSERT(pbp < peekbuf +
4854                                                        sizeof(peekbuf));
4855                                        *pbp++ = c;
4856                                        continue;
4857                                }
4858                                if (c == '\n')
4859                                {
4860                                        if (TrafficLogFile != NULL)
4861                                                (void) sm_io_fputs(TrafficLogFile,
4862                                                                   SM_TIME_DEFAULT,
4863                                                                   mci->mci_mailer->m_eol);
4864                                        if (sm_io_fputs(mci->mci_out,
4865                                                        SM_TIME_DEFAULT,
4866                                                        mci->mci_mailer->m_eol)
4867                                                        == SM_IO_EOF)
4868                                                continue;
4869                                        pos = 0;
4870                                        ostate = OS_HEAD;
4871                                }
4872                                else
4873                                {
4874                                        if (TrafficLogFile != NULL)
4875                                                (void) sm_io_putc(TrafficLogFile,
4876                                                                  SM_TIME_DEFAULT,
4877                                                                  (unsigned char) c);
4878                                        if (sm_io_putc(mci->mci_out,
4879                                                       SM_TIME_DEFAULT,
4880                                                       (unsigned char) c)
4881                                            == SM_IO_EOF)
4882                                        {
4883                                                dead = true;
4884                                                continue;
4885                                        }
4886                                        pos++;
4887                                        ostate = OS_INLINE;
4888                                }
4889                                break;
4890                        }
4891                }
4892
4893                /* make sure we are at the beginning of a line */
4894                if (bp > buf)
4895                {
4896                        if (TrafficLogFile != NULL)
4897                        {
4898                                for (xp = buf; xp < bp; xp++)
4899                                        (void) sm_io_putc(TrafficLogFile,
4900                                                          SM_TIME_DEFAULT,
4901                                                          (unsigned char) *xp);
4902                        }
4903                        for (xp = buf; xp < bp; xp++)
4904                        {
4905                                if (sm_io_putc(mci->mci_out, SM_TIME_DEFAULT,
4906                                               (unsigned char) *xp)
4907                                    == SM_IO_EOF)
4908                                {
4909                                        dead = true;
4910                                        break;
4911                                }
4912                        }
4913                        pos += bp - buf;
4914                }
4915                if (!dead && pos > 0)
4916                {
4917                        if (TrafficLogFile != NULL)
4918                                (void) sm_io_fputs(TrafficLogFile,
4919                                                   SM_TIME_DEFAULT,
4920                                                   mci->mci_mailer->m_eol);
4921                        if (sm_io_fputs(mci->mci_out, SM_TIME_DEFAULT,
4922                                           mci->mci_mailer->m_eol) == SM_IO_EOF)
4923                                goto writeerr;
4924                }
4925        }
4926
4927        if (sm_io_error(e->e_dfp))
4928        {
4929                syserr("putbody: %s/%cf%s: read error",
4930                       qid_printqueue(e->e_dfqgrp, e->e_dfqdir),
4931                       DATAFL_LETTER, e->e_id);
4932                ExitStat = EX_IOERR;
4933                ioerr = true;
4934        }
4935
4936endofmessage:
4937        /*
4938        **  Since mailfile() uses e_dfp in a child process,
4939        **  the file offset in the stdio library for the
4940        **  parent process will not agree with the in-kernel
4941        **  file offset since the file descriptor is shared
4942        **  between the processes.  Therefore, it is vital
4943        **  that the file always be rewound.  This forces the
4944        **  kernel offset (lseek) and stdio library (ftell)
4945        **  offset to match.
4946        */
4947
4948        save_errno = errno;
4949        if (e->e_dfp != NULL)
4950                (void) bfrewind(e->e_dfp);
4951
4952        /* some mailers want extra blank line at end of message */
4953        if (!dead && bitnset(M_BLANKEND, mci->mci_mailer->m_flags) &&
4954            buf[0] != '\0' && buf[0] != '\n')
4955        {
4956                if (!putline("", mci))
4957                        goto writeerr;
4958        }
4959
4960        if (!dead &&
4961            (sm_io_flush(mci->mci_out, SM_TIME_DEFAULT) == SM_IO_EOF ||
4962             (sm_io_error(mci->mci_out) && errno != EPIPE)))
4963        {
4964                save_errno = errno;
4965                syserr("putbody: write error");
4966                ExitStat = EX_IOERR;
4967                ioerr = true;
4968        }
4969
4970        errno = save_errno;
4971        return !dead && !ioerr;
4972
4973  writeerr:
4974        return false;
4975}
4976
4977/*
4978**  MAILFILE -- Send a message to a file.
4979**
4980**      If the file has the set-user-ID/set-group-ID bits set, but NO
4981**      execute bits, sendmail will try to become the owner of that file
4982**      rather than the real user.  Obviously, this only works if
4983**      sendmail runs as root.
4984**
4985**      This could be done as a subordinate mailer, except that it
4986**      is used implicitly to save messages in ~/dead.letter.  We
4987**      view this as being sufficiently important as to include it
4988**      here.  For example, if the system is dying, we shouldn't have
4989**      to create another process plus some pipes to save the message.
4990**
4991**      Parameters:
4992**              filename -- the name of the file to send to.
4993**              mailer -- mailer definition for recipient -- if NULL,
4994**                      use FileMailer.
4995**              ctladdr -- the controlling address header -- includes
4996**                      the userid/groupid to be when sending.
4997**              sfflags -- flags for opening.
4998**              e -- the current envelope.
4999**
5000**      Returns:
5001**              The exit code associated with the operation.
5002**
5003**      Side Effects:
5004**              none.
5005*/
5006
5007# define RETURN(st)                     exit(st);
5008
5009static jmp_buf  CtxMailfileTimeout;
5010
5011int
5012mailfile(filename, mailer, ctladdr, sfflags, e)
5013        char *volatile filename;
5014        MAILER *volatile mailer;
5015        ADDRESS *ctladdr;
5016        volatile long sfflags;
5017        register ENVELOPE *e;
5018{
5019        register SM_FILE_T *f;
5020        register pid_t pid = -1;
5021        volatile int mode;
5022        int len;
5023        off_t curoff;
5024        bool suidwarn = geteuid() == 0;
5025        char *p;
5026        char *volatile realfile;
5027        SM_EVENT *ev;
5028        char buf[MAXPATHLEN];
5029        char targetfile[MAXPATHLEN];
5030
5031        if (tTd(11, 1))
5032        {
5033                sm_dprintf("mailfile %s\n  ctladdr=", filename);
5034                printaddr(ctladdr, false);
5035        }
5036
5037        if (mailer == NULL)
5038                mailer = FileMailer;
5039
5040        if (e->e_xfp != NULL)
5041                (void) sm_io_flush(e->e_xfp, SM_TIME_DEFAULT);
5042
5043        /*
5044        **  Special case /dev/null.  This allows us to restrict file
5045        **  delivery to regular files only.
5046        */
5047
5048        if (sm_path_isdevnull(filename))
5049                return EX_OK;
5050
5051        /* check for 8-bit available */
5052        if (bitset(EF_HAS8BIT, e->e_flags) &&
5053            bitnset(M_7BITS, mailer->m_flags) &&
5054            (bitset(EF_DONT_MIME, e->e_flags) ||
5055             !(bitset(MM_MIME8BIT, MimeMode) ||
5056               (bitset(EF_IS_MIME, e->e_flags) &&
5057                bitset(MM_CVTMIME, MimeMode)))))
5058        {
5059                e->e_status = "5.6.3";
5060                usrerrenh(e->e_status,
5061                          "554 Cannot send 8-bit data to 7-bit destination");
5062                errno = 0;
5063                return EX_DATAERR;
5064        }
5065
5066        /* Find the actual file */
5067        if (SafeFileEnv != NULL && SafeFileEnv[0] != '\0')
5068        {
5069                len = strlen(SafeFileEnv);
5070
5071                if (strncmp(SafeFileEnv, filename, len) == 0)
5072                        filename += len;
5073
5074                if (len + strlen(filename) + 1 >= sizeof targetfile)
5075                {
5076                        syserr("mailfile: filename too long (%s/%s)",
5077                               SafeFileEnv, filename);
5078                        return EX_CANTCREAT;
5079                }
5080                (void) sm_strlcpy(targetfile, SafeFileEnv, sizeof targetfile);
5081                realfile = targetfile + len;
5082                if (*filename == '/')
5083                        filename++;
5084                if (*filename != '\0')
5085                {
5086                        /* paranoia: trailing / should be removed in readcf */
5087                        if (targetfile[len - 1] != '/')
5088                                (void) sm_strlcat(targetfile,
5089                                                  "/", sizeof targetfile);
5090                        (void) sm_strlcat(targetfile, filename,
5091                                          sizeof targetfile);
5092                }
5093        }
5094        else if (mailer->m_rootdir != NULL)
5095        {
5096                expand(mailer->m_rootdir, targetfile, sizeof targetfile, e);
5097                len = strlen(targetfile);
5098
5099                if (strncmp(targetfile, filename, len) == 0)
5100                        filename += len;
5101
5102                if (len + strlen(filename) + 1 >= sizeof targetfile)
5103                {
5104                        syserr("mailfile: filename too long (%s/%s)",
5105                               targetfile, filename);
5106                        return EX_CANTCREAT;
5107                }
5108                realfile = targetfile + len;
5109                if (targetfile[len - 1] != '/')
5110                        (void) sm_strlcat(targetfile, "/", sizeof targetfile);
5111                if (*filename == '/')
5112                        (void) sm_strlcat(targetfile, filename + 1,
5113                                          sizeof targetfile);
5114                else
5115                        (void) sm_strlcat(targetfile, filename,
5116                                          sizeof targetfile);
5117        }
5118        else
5119        {
5120                if (sm_strlcpy(targetfile, filename, sizeof targetfile) >=
5121                    sizeof targetfile)
5122                {
5123                        syserr("mailfile: filename too long (%s)", filename);
5124                        return EX_CANTCREAT;
5125                }
5126                realfile = targetfile;
5127        }
5128
5129        /*
5130        **  Fork so we can change permissions here.
5131        **      Note that we MUST use fork, not vfork, because of
5132        **      the complications of calling subroutines, etc.
5133        */
5134
5135
5136        /*
5137        **  Dispose of SIGCHLD signal catchers that may be laying
5138        **  around so that the waitfor() below will get it.
5139        */
5140
5141        (void) sm_signal(SIGCHLD, SIG_DFL);
5142
5143        DOFORK(fork);
5144
5145        if (pid < 0)
5146                return EX_OSERR;
5147        else if (pid == 0)
5148        {
5149                /* child -- actually write to file */
5150                struct stat stb;
5151                MCI mcibuf;
5152                int err;
5153                volatile int oflags = O_WRONLY|O_APPEND;
5154
5155                /* Reset global flags */
5156                RestartRequest = NULL;
5157                RestartWorkGroup = false;
5158                ShutdownRequest = NULL;
5159                PendingSignal = 0;
5160                CurrentPid = getpid();
5161
5162                if (e->e_lockfp != NULL)
5163                        (void) close(sm_io_getinfo(e->e_lockfp, SM_IO_WHAT_FD,
5164                                     NULL));
5165
5166                (void) sm_signal(SIGINT, SIG_DFL);
5167                (void) sm_signal(SIGHUP, SIG_DFL);
5168                (void) sm_signal(SIGTERM, SIG_DFL);
5169                (void) umask(OldUmask);
5170                e->e_to = filename;
5171                ExitStat = EX_OK;
5172
5173                if (setjmp(CtxMailfileTimeout) != 0)
5174                {
5175                        RETURN(EX_TEMPFAIL);
5176                }
5177
5178                if (TimeOuts.to_fileopen > 0)
5179                        ev = sm_setevent(TimeOuts.to_fileopen, mailfiletimeout,
5180                                         0);
5181                else
5182                        ev = NULL;
5183
5184                /* check file mode to see if set-user-ID */
5185                if (stat(targetfile, &stb) < 0)
5186                        mode = FileMode;
5187                else
5188                        mode = stb.st_mode;
5189
5190                /* limit the errors to those actually caused in the child */
5191                errno = 0;
5192                ExitStat = EX_OK;
5193
5194                /* Allow alias expansions to use the S_IS{U,G}ID bits */
5195                if ((ctladdr != NULL && !bitset(QALIAS, ctladdr->q_flags)) ||
5196                    bitset(SFF_RUNASREALUID, sfflags))
5197                {
5198                        /* ignore set-user-ID and set-group-ID bits */
5199                        mode &= ~(S_ISGID|S_ISUID);
5200                        if (tTd(11, 20))
5201                                sm_dprintf("mailfile: ignoring set-user-ID/set-group-ID bits\n");
5202                }
5203
5204                /* we have to open the data file BEFORE setuid() */
5205                if (e->e_dfp == NULL && bitset(EF_HAS_DF, e->e_flags))
5206                {
5207                        char *df = queuename(e, DATAFL_LETTER);
5208
5209                        e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, df,
5210                                              SM_IO_RDONLY, NULL);
5211                        if (e->e_dfp == NULL)
5212                        {
5213                                syserr("mailfile: Cannot open %s for %s from %s",
5214                                        df, e->e_to, e->e_from.q_paddr);
5215                        }
5216                }
5217
5218                /* select a new user to run as */
5219                if (!bitset(SFF_RUNASREALUID, sfflags))
5220                {
5221                        if (bitnset(M_SPECIFIC_UID, mailer->m_flags))
5222                        {
5223                                RealUserName = NULL;
5224                                RealUid = mailer->m_uid;
5225                                if (RunAsUid != 0 && RealUid != RunAsUid)
5226                                {
5227                                        /* Only root can change the uid */
5228                                        syserr("mailfile: insufficient privileges to change uid, RunAsUid=%d, RealUid=%d",
5229                                                (int) RunAsUid, (int) RealUid);
5230                                        RETURN(EX_TEMPFAIL);
5231                                }
5232                        }
5233                        else if (bitset(S_ISUID, mode))
5234                        {
5235                                RealUserName = NULL;
5236                                RealUid = stb.st_uid;
5237                        }
5238                        else if (ctladdr != NULL && ctladdr->q_uid != 0)
5239                        {
5240                                if (ctladdr->q_ruser != NULL)
5241                                        RealUserName = ctladdr->q_ruser;
5242                                else
5243                                        RealUserName = ctladdr->q_user;
5244                                RealUid = ctladdr->q_uid;
5245                        }
5246                        else if (mailer != NULL && mailer->m_uid != 0)
5247                        {
5248                                RealUserName = DefUser;
5249                                RealUid = mailer->m_uid;
5250                        }
5251                        else
5252                        {
5253                                RealUserName = DefUser;
5254                                RealUid = DefUid;
5255                        }
5256
5257                        /* select a new group to run as */
5258                        if (bitnset(M_SPECIFIC_UID, mailer->m_flags))
5259                        {
5260                                RealGid = mailer->m_gid;
5261                                if (RunAsUid != 0 &&
5262                                    (RealGid != getgid() ||
5263                                     RealGid != getegid()))
5264                                {
5265                                        /* Only root can change the gid */
5266                                        syserr("mailfile: insufficient privileges to change gid, RealGid=%d, RunAsUid=%d, gid=%d, egid=%d",
5267                                               (int) RealGid, (int) RunAsUid,
5268                                               (int) getgid(), (int) getegid());
5269                                        RETURN(EX_TEMPFAIL);
5270                                }
5271                        }
5272                        else if (bitset(S_ISGID, mode))
5273                                RealGid = stb.st_gid;
5274                        else if (ctladdr != NULL &&
5275                                 ctladdr->q_uid == DefUid &&
5276                                 ctladdr->q_gid == 0)
5277                        {
5278                                /*
5279                                **  Special case:  This means it is an
5280                                **  alias and we should act as DefaultUser.
5281                                **  See alias()'s comments.
5282                                */
5283
5284                                RealGid = DefGid;
5285                                RealUserName = DefUser;
5286                        }
5287                        else if (ctladdr != NULL && ctladdr->q_uid != 0)
5288                                RealGid = ctladdr->q_gid;
5289                        else if (mailer != NULL && mailer->m_gid != 0)
5290                                RealGid = mailer->m_gid;
5291                        else
5292                                RealGid = DefGid;
5293                }
5294
5295                /* last ditch */
5296                if (!bitset(SFF_ROOTOK, sfflags))
5297                {
5298                        if (RealUid == 0)
5299                                RealUid = DefUid;
5300                        if (RealGid == 0)
5301                                RealGid = DefGid;
5302                }
5303
5304                /* set group id list (needs /etc/group access) */
5305                if (RealUserName != NULL && !DontInitGroups)
5306                {
5307                        if (initgroups(RealUserName, RealGid) == -1 && suidwarn)
5308                        {
5309                                syserr("mailfile: initgroups(%s, %d) failed",
5310                                        RealUserName, RealGid);
5311                                RETURN(EX_TEMPFAIL);
5312                        }
5313                }
5314                else
5315                {
5316                        GIDSET_T gidset[1];
5317
5318                        gidset[0] = RealGid;
5319                        if (setgroups(1, gidset) == -1 && suidwarn)
5320                        {
5321                                syserr("mailfile: setgroups() failed");
5322                                RETURN(EX_TEMPFAIL);
5323                        }
5324                }
5325
5326                /*
5327                **  If you have a safe environment, go into it.
5328                */
5329
5330                if (realfile != targetfile)
5331                {
5332                        char save;
5333
5334                        save = *realfile;
5335                        *realfile = '\0';
5336                        if (tTd(11, 20))
5337                                sm_dprintf("mailfile: chroot %s\n", targetfile);
5338                        if (chroot(targetfile) < 0)
5339                        {
5340                                syserr("mailfile: Cannot chroot(%s)",
5341                                       targetfile);
5342                                RETURN(EX_CANTCREAT);
5343                        }
5344                        *realfile = save;
5345                }
5346
5347                if (tTd(11, 40))
5348                        sm_dprintf("mailfile: deliver to %s\n", realfile);
5349
5350                if (chdir("/") < 0)
5351                {
5352                        syserr("mailfile: cannot chdir(/)");
5353                        RETURN(EX_CANTCREAT);
5354                }
5355
5356                /* now reset the group and user ids */
5357                endpwent();
5358                sm_mbdb_terminate();
5359                if (setgid(RealGid) < 0 && suidwarn)
5360                {
5361                        syserr("mailfile: setgid(%ld) failed", (long) RealGid);
5362                        RETURN(EX_TEMPFAIL);
5363                }
5364                vendor_set_uid(RealUid);
5365                if (setuid(RealUid) < 0 && suidwarn)
5366                {
5367                        syserr("mailfile: setuid(%ld) failed", (long) RealUid);
5368                        RETURN(EX_TEMPFAIL);
5369                }
5370
5371                if (tTd(11, 2))
5372                        sm_dprintf("mailfile: running as r/euid=%d/%d, r/egid=%d/%d\n",
5373                                (int) getuid(), (int) geteuid(),
5374                                (int) getgid(), (int) getegid());
5375
5376
5377                /* move into some "safe" directory */
5378                if (mailer->m_execdir != NULL)
5379                {
5380                        char *q;
5381
5382                        for (p = mailer->m_execdir; p != NULL; p = q)
5383                        {
5384                                q = strchr(p, ':');
5385                                if (q != NULL)
5386                                        *q = '\0';
5387                                expand(p, buf, sizeof buf, e);
5388                                if (q != NULL)
5389                                        *q++ = ':';
5390                                if (tTd(11, 20))
5391                                        sm_dprintf("mailfile: trydir %s\n",
5392                                                   buf);
5393                                if (buf[0] != '\0' && chdir(buf) >= 0)
5394                                        break;
5395                        }
5396                }
5397
5398                /*
5399                **  Recheck the file after we have assumed the ID of the
5400                **  delivery user to make sure we can deliver to it as
5401                **  that user.  This is necessary if sendmail is running
5402                **  as root and the file is on an NFS mount which treats
5403                **  root as nobody.
5404                */
5405
5406#if HASLSTAT
5407                if (bitnset(DBS_FILEDELIVERYTOSYMLINK, DontBlameSendmail))
5408                        err = stat(realfile, &stb);
5409                else
5410                        err = lstat(realfile, &stb);
5411#else /* HASLSTAT */
5412                err = stat(realfile, &stb);
5413#endif /* HASLSTAT */
5414
5415                if (err < 0)
5416                {
5417                        stb.st_mode = ST_MODE_NOFILE;
5418                        mode = FileMode;
5419                        oflags |= O_CREAT|O_EXCL;
5420                }
5421                else if (bitset(S_IXUSR|S_IXGRP|S_IXOTH, mode) ||
5422                         (!bitnset(DBS_FILEDELIVERYTOHARDLINK,
5423                                   DontBlameSendmail) &&
5424                          stb.st_nlink != 1) ||
5425                         (realfile != targetfile && !S_ISREG(mode)))
5426                        exit(EX_CANTCREAT);
5427                else
5428                        mode = stb.st_mode;
5429
5430                if (!bitnset(DBS_FILEDELIVERYTOSYMLINK, DontBlameSendmail))
5431                        sfflags |= SFF_NOSLINK;
5432                if (!bitnset(DBS_FILEDELIVERYTOHARDLINK, DontBlameSendmail))
5433                        sfflags |= SFF_NOHLINK;
5434                sfflags &= ~SFF_OPENASROOT;
5435                f = safefopen(realfile, oflags, mode, sfflags);
5436                if (f == NULL)
5437                {
5438                        if (transienterror(errno))
5439                        {
5440                                usrerr("454 4.3.0 cannot open %s: %s",
5441                                       shortenstring(realfile, MAXSHORTSTR),
5442                                       sm_errstring(errno));
5443                                RETURN(EX_TEMPFAIL);
5444                        }
5445                        else
5446                        {
5447                                usrerr("554 5.3.0 cannot open %s: %s",
5448                                       shortenstring(realfile, MAXSHORTSTR),
5449                                       sm_errstring(errno));
5450                                RETURN(EX_CANTCREAT);
5451                        }
5452                }
5453                if (filechanged(realfile, sm_io_getinfo(f, SM_IO_WHAT_FD, NULL),
5454                    &stb))
5455                {
5456                        syserr("554 5.3.0 file changed after open");
5457                        RETURN(EX_CANTCREAT);
5458                }
5459                if (fstat(sm_io_getinfo(f, SM_IO_WHAT_FD, NULL), &stb) < 0)
5460                {
5461                        syserr("554 5.3.0 cannot fstat %s",
5462                                sm_errstring(errno));
5463                        RETURN(EX_CANTCREAT);
5464                }
5465
5466                curoff = stb.st_size;
5467
5468                if (ev != NULL)
5469                        sm_clrevent(ev);
5470
5471                memset(&mcibuf, '\0', sizeof mcibuf);
5472                mcibuf.mci_mailer = mailer;
5473                mcibuf.mci_out = f;
5474                if (bitnset(M_7BITS, mailer->m_flags))
5475                        mcibuf.mci_flags |= MCIF_7BIT;
5476
5477                /* clear out per-message flags from connection structure */
5478                mcibuf.mci_flags &= ~(MCIF_CVT7TO8|MCIF_CVT8TO7);
5479
5480                if (bitset(EF_HAS8BIT, e->e_flags) &&
5481                    !bitset(EF_DONT_MIME, e->e_flags) &&
5482                    bitnset(M_7BITS, mailer->m_flags))
5483                        mcibuf.mci_flags |= MCIF_CVT8TO7;
5484
5485#if MIME7TO8
5486                if (bitnset(M_MAKE8BIT, mailer->m_flags) &&
5487                    !bitset(MCIF_7BIT, mcibuf.mci_flags) &&
5488                    (p = hvalue("Content-Transfer-Encoding", e->e_header)) != NULL &&
5489                    (sm_strcasecmp(p, "quoted-printable") == 0 ||
5490                     sm_strcasecmp(p, "base64") == 0) &&
5491                    (p = hvalue("Content-Type", e->e_header)) != NULL)
5492                {
5493                        /* may want to convert 7 -> 8 */
5494                        /* XXX should really parse it here -- and use a class XXX */
5495                        if (sm_strncasecmp(p, "text/plain", 10) == 0 &&
5496                            (p[10] == '\0' || p[10] == ' ' || p[10] == ';'))
5497                                mcibuf.mci_flags |= MCIF_CVT7TO8;
5498                }
5499#endif /* MIME7TO8 */
5500
5501                if (!putfromline(&mcibuf, e) ||
5502                    !(*e->e_puthdr)(&mcibuf, e->e_header, e, M87F_OUTER) ||
5503                    !(*e->e_putbody)(&mcibuf, e, NULL) ||
5504                    !putline("\n", &mcibuf) ||
5505                    (sm_io_flush(f, SM_TIME_DEFAULT) != 0 ||
5506                    (SuperSafe != SAFE_NO &&
5507                     fsync(sm_io_getinfo(f, SM_IO_WHAT_FD, NULL)) < 0) ||
5508                    sm_io_error(f)))
5509                {
5510                        setstat(EX_IOERR);
5511#if !NOFTRUNCATE
5512                        (void) ftruncate(sm_io_getinfo(f, SM_IO_WHAT_FD, NULL),
5513                                         curoff);
5514#endif /* !NOFTRUNCATE */
5515                }
5516
5517                /* reset ISUID & ISGID bits for paranoid systems */
5518#if HASFCHMOD
5519                (void) fchmod(sm_io_getinfo(f, SM_IO_WHAT_FD, NULL),
5520                              (MODE_T) mode);
5521#else /* HASFCHMOD */
5522                (void) chmod(filename, (MODE_T) mode);
5523#endif /* HASFCHMOD */
5524                if (sm_io_close(f, SM_TIME_DEFAULT) < 0)
5525                        setstat(EX_IOERR);
5526                (void) sm_io_flush(smioout, SM_TIME_DEFAULT);
5527                (void) setuid(RealUid);
5528                exit(ExitStat);
5529                /* NOTREACHED */
5530        }
5531        else
5532        {
5533                /* parent -- wait for exit status */
5534                int st;
5535
5536                st = waitfor(pid);
5537                if (st == -1)
5538                {
5539                        syserr("mailfile: %s: wait", mailer->m_name);
5540                        return EX_SOFTWARE;
5541                }
5542                if (WIFEXITED(st))
5543                {
5544                        errno = 0;
5545                        return (WEXITSTATUS(st));
5546                }
5547                else
5548                {
5549                        syserr("mailfile: %s: child died on signal %d",
5550                               mailer->m_name, st);
5551                        return EX_UNAVAILABLE;
5552                }
5553                /* NOTREACHED */
5554        }
5555        return EX_UNAVAILABLE;  /* avoid compiler warning on IRIX */
5556}
5557
5558static void
5559mailfiletimeout()
5560{
5561        /*
5562        **  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
5563        **      ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
5564        **      DOING.
5565        */
5566
5567        errno = ETIMEDOUT;
5568        longjmp(CtxMailfileTimeout, 1);
5569}
5570/*
5571**  HOSTSIGNATURE -- return the "signature" for a host.
5572**
5573**      The signature describes how we are going to send this -- it
5574**      can be just the hostname (for non-Internet hosts) or can be
5575**      an ordered list of MX hosts.
5576**
5577**      Parameters:
5578**              m -- the mailer describing this host.
5579**              host -- the host name.
5580**
5581**      Returns:
5582**              The signature for this host.
5583**
5584**      Side Effects:
5585**              Can tweak the symbol table.
5586*/
5587
5588#define MAXHOSTSIGNATURE        8192    /* max len of hostsignature */
5589
5590char *
5591hostsignature(m, host)
5592        register MAILER *m;
5593        char *host;
5594{
5595        register char *p;
5596        register STAB *s;
5597        time_t now;
5598#if NAMED_BIND
5599        char sep = ':';
5600        char prevsep = ':';
5601        int i;
5602        int len;
5603        int nmx;
5604        int hl;
5605        char *hp;
5606        char *endp;
5607        int oldoptions = _res.options;
5608        char *mxhosts[MAXMXHOSTS + 1];
5609        unsigned short mxprefs[MAXMXHOSTS + 1];
5610#endif /* NAMED_BIND */
5611
5612        if (tTd(17, 3))
5613                sm_dprintf("hostsignature(%s)\n", host);
5614
5615        /*
5616        **  If local delivery (and not remote), just return a constant.
5617        */
5618
5619        if (bitnset(M_LOCALMAILER, m->m_flags) &&
5620            strcmp(m->m_mailer, "[IPC]") != 0 &&
5621            !(m->m_argv[0] != NULL && strcmp(m->m_argv[0], "TCP") == 0))
5622                return "localhost";
5623
5624        /*
5625        **  Check to see if this uses IPC -- if not, it can't have MX records.
5626        */
5627
5628        if (strcmp(m->m_mailer, "[IPC]") != 0 ||
5629            CurEnv->e_sendmode == SM_DEFER)
5630        {
5631                /* just an ordinary mailer or deferred mode */
5632                return host;
5633        }
5634#if NETUNIX
5635        else if (m->m_argv[0] != NULL &&
5636                 strcmp(m->m_argv[0], "FILE") == 0)
5637        {
5638                /* rendezvous in the file system, no MX records */
5639                return host;
5640        }
5641#endif /* NETUNIX */
5642
5643        /*
5644        **  Look it up in the symbol table.
5645        */
5646
5647        now = curtime();
5648        s = stab(host, ST_HOSTSIG, ST_ENTER);
5649        if (s->s_hostsig.hs_sig != NULL)
5650        {
5651                if (s->s_hostsig.hs_exp >= now)
5652                {
5653                        if (tTd(17, 3))
5654                                sm_dprintf("hostsignature(): stab(%s) found %s\n", host,
5655                                           s->s_hostsig.hs_sig);
5656                        return s->s_hostsig.hs_sig;
5657                }
5658
5659                /* signature is expired: clear it */
5660                sm_free(s->s_hostsig.hs_sig);
5661                s->s_hostsig.hs_sig = NULL;
5662        }
5663
5664        /* set default TTL */
5665        s->s_hostsig.hs_exp = now + SM_DEFAULT_TTL;
5666
5667        /*
5668        **  Not already there or expired -- create a signature.
5669        */
5670
5671#if NAMED_BIND
5672        if (ConfigLevel < 2)
5673                _res.options &= ~(RES_DEFNAMES | RES_DNSRCH);   /* XXX */
5674
5675        for (hp = host; hp != NULL; hp = endp)
5676        {
5677#if NETINET6
5678                if (*hp == '[')
5679                {
5680                        endp = strchr(hp + 1, ']');
5681                        if (endp != NULL)
5682                                endp = strpbrk(endp + 1, ":,");
5683                }
5684                else
5685                        endp = strpbrk(hp, ":,");
5686#else /* NETINET6 */
5687                endp = strpbrk(hp, ":,");
5688#endif /* NETINET6 */
5689                if (endp != NULL)
5690                {
5691                        sep = *endp;
5692                        *endp = '\0';
5693                }
5694
5695                if (bitnset(M_NOMX, m->m_flags))
5696                {
5697                        /* skip MX lookups */
5698                        nmx = 1;
5699                        mxhosts[0] = hp;
5700                }
5701                else
5702                {
5703                        auto int rcode;
5704                        int ttl;
5705
5706                        nmx = getmxrr(hp, mxhosts, mxprefs, true, &rcode, true,
5707                                      &ttl);
5708                        if (nmx <= 0)
5709                        {
5710                                int save_errno;
5711                                register MCI *mci;
5712
5713                                /* update the connection info for this host */
5714                                save_errno = errno;
5715                                mci = mci_get(hp, m);
5716                                mci->mci_errno = save_errno;
5717                                mci->mci_herrno = h_errno;
5718                                mci->mci_lastuse = now;
5719                                if (rcode == EX_NOHOST)
5720                                        mci_setstat(mci, rcode, "5.1.2",
5721                                                    "550 Host unknown");
5722                                else
5723                                        mci_setstat(mci, rcode, NULL, NULL);
5724
5725                                /* use the original host name as signature */
5726                                nmx = 1;
5727                                mxhosts[0] = hp;
5728                        }
5729                        if (tTd(17, 3))
5730                                sm_dprintf("hostsignature(): getmxrr() returned %d, mxhosts[0]=%s\n",
5731                                           nmx, mxhosts[0]);
5732
5733                        /*
5734                        **  Set new TTL: we use only one!
5735                        **      We could try to use the minimum instead.
5736                        */
5737
5738                        s->s_hostsig.hs_exp = now + SM_MIN(ttl, SM_DEFAULT_TTL);
5739                }
5740
5741                len = 0;
5742                for (i = 0; i < nmx; i++)
5743                        len += strlen(mxhosts[i]) + 1;
5744                if (s->s_hostsig.hs_sig != NULL)
5745                        len += strlen(s->s_hostsig.hs_sig) + 1;
5746                if (len < 0 || len >= MAXHOSTSIGNATURE)
5747                {
5748                        sm_syslog(LOG_WARNING, NOQID, "hostsignature for host '%s' exceeds maxlen (%d): %d",
5749                                  host, MAXHOSTSIGNATURE, len);
5750                        len = MAXHOSTSIGNATURE;
5751                }
5752                p = sm_pmalloc_x(len);
5753                if (s->s_hostsig.hs_sig != NULL)
5754                {
5755                        (void) sm_strlcpy(p, s->s_hostsig.hs_sig, len);
5756                        sm_free(s->s_hostsig.hs_sig); /* XXX */
5757                        s->s_hostsig.hs_sig = p;
5758                        hl = strlen(p);
5759                        p += hl;
5760                        *p++ = prevsep;
5761                        len -= hl + 1;
5762                }
5763                else
5764                        s->s_hostsig.hs_sig = p;
5765                for (i = 0; i < nmx; i++)
5766                {
5767                        hl = strlen(mxhosts[i]);
5768                        if (len - 1 < hl || len <= 1)
5769                        {
5770                                /* force to drop out of outer loop */
5771                                len = -1;
5772                                break;
5773                        }
5774                        if (i != 0)
5775                        {
5776                                if (mxprefs[i] == mxprefs[i - 1])
5777                                        *p++ = ',';
5778                                else
5779                                        *p++ = ':';
5780                                len--;
5781                        }
5782                        (void) sm_strlcpy(p, mxhosts[i], len);
5783                        p += hl;
5784                        len -= hl;
5785                }
5786
5787                /*
5788                **  break out of loop if len exceeded MAXHOSTSIGNATURE
5789                **  because we won't have more space for further hosts
5790                **  anyway (separated by : in the .cf file).
5791                */
5792
5793                if (len < 0)
5794                        break;
5795                if (endp != NULL)
5796                        *endp++ = sep;
5797                prevsep = sep;
5798        }
5799        makelower(s->s_hostsig.hs_sig);
5800        if (ConfigLevel < 2)
5801                _res.options = oldoptions;
5802#else /* NAMED_BIND */
5803        /* not using BIND -- the signature is just the host name */
5804        /*
5805        **  'host' points to storage that will be freed after we are
5806        **  done processing the current envelope, so we copy it.
5807        */
5808        s->s_hostsig.hs_sig = sm_pstrdup_x(host);
5809#endif /* NAMED_BIND */
5810        if (tTd(17, 1))
5811                sm_dprintf("hostsignature(%s) = %s\n", host, s->s_hostsig.hs_sig);
5812        return s->s_hostsig.hs_sig;
5813}
5814/*
5815**  PARSE_HOSTSIGNATURE -- parse the "signature" and return MX host array.
5816**
5817**      The signature describes how we are going to send this -- it
5818**      can be just the hostname (for non-Internet hosts) or can be
5819**      an ordered list of MX hosts which must be randomized for equal
5820**      MX preference values.
5821**
5822**      Parameters:
5823**              sig -- the host signature.
5824**              mxhosts -- array to populate.
5825**              mailer -- mailer.
5826**
5827**      Returns:
5828**              The number of hosts inserted into mxhosts array.
5829**
5830**      Side Effects:
5831**              Randomizes equal MX preference hosts in mxhosts.
5832*/
5833
5834static int
5835parse_hostsignature(sig, mxhosts, mailer)
5836        char *sig;
5837        char **mxhosts;
5838        MAILER *mailer;
5839{
5840        unsigned short curpref = 0;
5841        int nmx = 0, i, j;      /* NOTE: i, j, and nmx must have same type */
5842        char *hp, *endp;
5843        unsigned short prefer[MAXMXHOSTS];
5844        long rndm[MAXMXHOSTS];
5845
5846        for (hp = sig; hp != NULL; hp = endp)
5847        {
5848                char sep = ':';
5849
5850#if NETINET6
5851                if (*hp == '[')
5852                {
5853                        endp = strchr(hp + 1, ']');
5854                        if (endp != NULL)
5855                                endp = strpbrk(endp + 1, ":,");
5856                }
5857                else
5858                        endp = strpbrk(hp, ":,");
5859#else /* NETINET6 */
5860                endp = strpbrk(hp, ":,");
5861#endif /* NETINET6 */
5862                if (endp != NULL)
5863                {
5864                        sep = *endp;
5865                        *endp = '\0';
5866                }
5867
5868                mxhosts[nmx] = hp;
5869                prefer[nmx] = curpref;
5870                if (mci_match(hp, mailer))
5871                        rndm[nmx] = 0;
5872                else
5873                        rndm[nmx] = get_random();
5874
5875                if (endp != NULL)
5876                {
5877                        /*
5878                        **  Since we don't have the original MX prefs,
5879                        **  make our own.  If the separator is a ':', that
5880                        **  means the preference for the next host will be
5881                        **  higher than this one, so simply increment curpref.
5882                        */
5883
5884                        if (sep == ':')
5885                                curpref++;
5886
5887                        *endp++ = sep;
5888                }
5889                if (++nmx >= MAXMXHOSTS)
5890                        break;
5891        }
5892
5893        /* sort the records using the random factor for equal preferences */
5894        for (i = 0; i < nmx; i++)
5895        {
5896                for (j = i + 1; j < nmx; j++)
5897                {
5898                        /*
5899                        **  List is already sorted by MX preference, only
5900                        **  need to look for equal preference MX records
5901                        */
5902
5903                        if (prefer[i] < prefer[j])
5904                                break;
5905
5906                        if (prefer[i] > prefer[j] ||
5907                            (prefer[i] == prefer[j] && rndm[i] > rndm[j]))
5908                        {
5909                                register unsigned short tempp;
5910                                register long tempr;
5911                                register char *temp1;
5912
5913                                tempp = prefer[i];
5914                                prefer[i] = prefer[j];
5915                                prefer[j] = tempp;
5916                                temp1 = mxhosts[i];
5917                                mxhosts[i] = mxhosts[j];
5918                                mxhosts[j] = temp1;
5919                                tempr = rndm[i];
5920                                rndm[i] = rndm[j];
5921                                rndm[j] = tempr;
5922                        }
5923                }
5924        }
5925        return nmx;
5926}
5927
5928# if STARTTLS
5929static SSL_CTX  *clt_ctx = NULL;
5930static bool     tls_ok_clt = true;
5931
5932/*
5933**  SETCLTTLS -- client side TLS: allow/disallow.
5934**
5935**      Parameters:
5936**              tls_ok -- should tls be done?
5937**
5938**      Returns:
5939**              none.
5940**
5941**      Side Effects:
5942**              sets tls_ok_clt (static variable in this module)
5943*/
5944
5945void
5946setclttls(tls_ok)
5947        bool tls_ok;
5948{
5949        tls_ok_clt = tls_ok;
5950        return;
5951}
5952/*
5953**  INITCLTTLS -- initialize client side TLS
5954**
5955**      Parameters:
5956**              tls_ok -- should tls initialization be done?
5957**
5958**      Returns:
5959**              succeeded?
5960**
5961**      Side Effects:
5962**              sets tls_ok_clt (static variable in this module)
5963*/
5964
5965bool
5966initclttls(tls_ok)
5967        bool tls_ok;
5968{
5969        if (!tls_ok_clt)
5970                return false;
5971        tls_ok_clt = tls_ok;
5972        if (!tls_ok_clt)
5973                return false;
5974        if (clt_ctx != NULL)
5975                return true;    /* already done */
5976        tls_ok_clt = inittls(&clt_ctx, TLS_I_CLT, false, CltCertFile,
5977                             CltKeyFile, CACertPath, CACertFile, DHParams);
5978        return tls_ok_clt;
5979}
5980
5981/*
5982**  STARTTLS -- try to start secure connection (client side)
5983**
5984**      Parameters:
5985**              m -- the mailer.
5986**              mci -- the mailer connection info.
5987**              e -- the envelope.
5988**
5989**      Returns:
5990**              success?
5991**              (maybe this should be some other code than EX_
5992**              that denotes which stage failed.)
5993*/
5994
5995static int
5996starttls(m, mci, e)
5997        MAILER *m;
5998        MCI *mci;
5999        ENVELOPE *e;
6000{
6001        int smtpresult;
6002        int result = 0;
6003        int rfd, wfd;
6004        SSL *clt_ssl = NULL;
6005        time_t tlsstart;
6006
6007        if (clt_ctx == NULL && !initclttls(true))
6008                return EX_TEMPFAIL;
6009        smtpmessage("STARTTLS", m, mci);
6010
6011        /* get the reply */
6012        smtpresult = reply(m, mci, e, TimeOuts.to_starttls, NULL, NULL);
6013
6014        /* check return code from server */
6015        if (smtpresult == 454)
6016                return EX_TEMPFAIL;
6017        if (smtpresult == 501)
6018                return EX_USAGE;
6019        if (smtpresult == -1)
6020                return smtpresult;
6021        if (smtpresult != 220)
6022                return EX_PROTOCOL;
6023
6024        if (LogLevel > 13)
6025                sm_syslog(LOG_INFO, NOQID, "STARTTLS=client, start=ok");
6026
6027        /* start connection */
6028        if ((clt_ssl = SSL_new(clt_ctx)) == NULL)
6029        {
6030                if (LogLevel > 5)
6031                {
6032                        sm_syslog(LOG_ERR, NOQID,
6033                                  "STARTTLS=client, error: SSL_new failed");
6034                        if (LogLevel > 9)
6035                                tlslogerr("client");
6036                }
6037                return EX_SOFTWARE;
6038        }
6039
6040        rfd = sm_io_getinfo(mci->mci_in, SM_IO_WHAT_FD, NULL);
6041        wfd = sm_io_getinfo(mci->mci_out, SM_IO_WHAT_FD, NULL);
6042
6043        /* SSL_clear(clt_ssl); ? */
6044        if (rfd < 0 || wfd < 0 ||
6045            (result = SSL_set_rfd(clt_ssl, rfd)) != 1 ||
6046            (result = SSL_set_wfd(clt_ssl, wfd)) != 1)
6047        {
6048                if (LogLevel > 5)
6049                {
6050                        sm_syslog(LOG_ERR, NOQID,
6051                                  "STARTTLS=client, error: SSL_set_xfd failed=%d",
6052                                  result);
6053                        if (LogLevel > 9)
6054                                tlslogerr("client");
6055                }
6056                return EX_SOFTWARE;
6057        }
6058        SSL_set_connect_state(clt_ssl);
6059        tlsstart = curtime();
6060
6061ssl_retry:
6062        if ((result = SSL_connect(clt_ssl)) <= 0)
6063        {
6064                int i, ssl_err;
6065
6066                ssl_err = SSL_get_error(clt_ssl, result);
6067                i = tls_retry(clt_ssl, rfd, wfd, tlsstart,
6068                        TimeOuts.to_starttls, ssl_err, "client");
6069                if (i > 0)
6070                        goto ssl_retry;
6071
6072                if (LogLevel > 5)
6073                {
6074                        sm_syslog(LOG_WARNING, NOQID,
6075                                  "STARTTLS=client, error: connect failed=%d, SSL_error=%d, errno=%d, retry=%d",
6076                                  result, ssl_err, errno, i);
6077                        if (LogLevel > 8)
6078                                tlslogerr("client");
6079                }
6080
6081                SSL_free(clt_ssl);
6082                clt_ssl = NULL;
6083                return EX_SOFTWARE;
6084        }
6085        mci->mci_ssl = clt_ssl;
6086        result = tls_get_info(mci->mci_ssl, false, mci->mci_host,
6087                              &mci->mci_macro, true);
6088
6089        /* switch to use TLS... */
6090        if (sfdctls(&mci->mci_in, &mci->mci_out, mci->mci_ssl) == 0)
6091                return EX_OK;
6092
6093        /* failure */
6094        SSL_free(clt_ssl);
6095        clt_ssl = NULL;
6096        return EX_SOFTWARE;
6097}
6098/*
6099**  ENDTLSCLT -- shutdown secure connection (client side)
6100**
6101**      Parameters:
6102**              mci -- the mailer connection info.
6103**
6104**      Returns:
6105**              success?
6106*/
6107
6108static int
6109endtlsclt(mci)
6110        MCI *mci;
6111{
6112        int r;
6113
6114        if (!bitset(MCIF_TLSACT, mci->mci_flags))
6115                return EX_OK;
6116        r = endtls(mci->mci_ssl, "client");
6117        mci->mci_flags &= ~MCIF_TLSACT;
6118        return r;
6119}
6120# endif /* STARTTLS */
6121# if STARTTLS || SASL
6122/*
6123**  ISCLTFLGSET -- check whether client flag is set.
6124**
6125**      Parameters:
6126**              e -- envelope.
6127**              flag -- flag to check in {client_flags}
6128**
6129**      Returns:
6130**              true iff flag is set.
6131*/
6132
6133static bool
6134iscltflgset(e, flag)
6135        ENVELOPE *e;
6136        int flag;
6137{
6138        char *p;
6139
6140        p = macvalue(macid("{client_flags}"), e);
6141        if (p == NULL)
6142                return false;
6143        for (; *p != '\0'; p++)
6144        {
6145                /* look for just this one flag */
6146                if (*p == (char) flag)
6147                        return true;
6148        }
6149        return false;
6150}
6151# endif /* STARTTLS || SASL */
Note: See TracBrowser for help on using the repository browser.