avoid MIMEing RFC1049 messages
[unix-history] / usr / src / usr.sbin / sendmail / src / deliver.c
CommitLineData
d185cb11 1/*
792e6158 2 * Copyright (c) 1983, 1995 Eric P. Allman
31de980b
KB
3 * Copyright (c) 1988, 1993
4 * The Regents of the University of California. All rights reserved.
bee79b64 5 *
417f7a11 6 * %sccs.include.redist.c%
bee79b64 7 */
d185cb11
DF
8
9#ifndef lint
a5386d1b 10static char sccsid[] = "@(#)deliver.c 8.159 (Berkeley) %G%";
bee79b64 11#endif /* not lint */
d185cb11 12
97543758 13#include "sendmail.h"
7b6e7aee 14#include <errno.h>
efe7f723 15#if NAMED_BIND
f28c9fe2 16#include <resolv.h>
8e5c6745
EA
17
18extern int h_errno;
35af2f06 19#endif
b3cbe40f 20
965c2488
EA
21extern char SmtpError[];
22
b3cbe40f 23/*
6acfa498 24** SENDALL -- actually send all the messages.
b3cbe40f 25**
b3cbe40f 26** Parameters:
6acfa498
EA
27** e -- the envelope to send.
28** mode -- the delivery mode to use. If SM_DEFAULT, use
29** the current e->e_sendmode.
b3cbe40f
EA
30**
31** Returns:
6acfa498 32** none.
b3cbe40f
EA
33**
34** Side Effects:
6acfa498
EA
35** Scans the send lists and sends everything it finds.
36** Delivers any appropriate error messages.
37** If we are running in a non-interactive mode, takes the
38** appropriate action.
b3cbe40f
EA
39*/
40
ea07b2d2 41void
6acfa498
EA
42sendall(e, mode)
43 ENVELOPE *e;
44 char mode;
b3cbe40f 45{
6acfa498
EA
46 register ADDRESS *q;
47 char *owner;
48 int otherowners;
11024b4c 49 bool oldverbose = Verbose;
1ce944f0 50 bool somedeliveries = FALSE;
11024b4c 51 int pid;
ea07b2d2 52 extern void sendenvelope();
1d303d98
EA
53 int pid;
54#ifdef LOCKF
55 struct flock lfd;
56#endif
b3cbe40f 57
d4f6a25e
EA
58 /*
59 ** If we have had global, fatal errors, don't bother sending
60 ** the message at all if we are in SMTP mode. Local errors
61 ** (e.g., a single address failing) will still cause the other
62 ** addresses to be sent.
63 */
64
198d9e9c
EA
65 if (bitset(EF_FATALERRS, e->e_flags) &&
66 (OpMode == MD_SMTP || OpMode == MD_DAEMON))
004a2b9c 67 {
004a2b9c
EA
68 e->e_flags |= EF_CLRQUEUE;
69 return;
70 }
71
6acfa498 72 /* determine actual delivery mode */
fc826a82 73 CurrentLA = getla();
6acfa498
EA
74 if (mode == SM_DEFAULT)
75 {
6acfa498
EA
76 mode = e->e_sendmode;
77 if (mode != SM_VERIFY &&
78 shouldqueue(e->e_msgpriority, e->e_ctime))
79 mode = SM_QUEUE;
f28c9fe2 80 }
3135d20c 81
6acfa498 82 if (tTd(13, 1))
3135d20c 83 {
1ce944f0
EA
84 extern void printenvflags();
85
b5618bbc
EA
86 printf("\n===== SENDALL: mode %c, id %s, e_from ",
87 mode, e->e_id);
6acfa498 88 printaddr(&e->e_from, FALSE);
1ce944f0
EA
89 printf("\te_flags = ");
90 printenvflags(e);
6acfa498
EA
91 printf("sendqueue:\n");
92 printaddr(e->e_sendqueue, TRUE);
3135d20c
EA
93 }
94
a530c75f 95 /*
6acfa498
EA
96 ** Do any preprocessing necessary for the mode we are running.
97 ** Check to make sure the hop count is reasonable.
98 ** Delete sends to the sender in mailing lists.
a530c75f
EA
99 */
100
6acfa498 101 CurEnv = e;
a530c75f 102
6acfa498 103 if (e->e_hopcount > MaxHopCount)
779597d8 104 {
6acfa498 105 errno = 0;
1ce944f0 106 queueup(e, TRUE, mode == SM_QUEUE);
ec33213e 107 e->e_flags |= EF_FATALERRS|EF_PM_NOTIFY|EF_CLRQUEUE;
7905af2d 108 syserr("554 Too many hops %d (%d max): from %s via %s, to %s",
6acfa498 109 e->e_hopcount, MaxHopCount, e->e_from.q_paddr,
389c0d5e
EA
110 RealHostName == NULL ? "localhost" : RealHostName,
111 e->e_sendqueue->q_paddr);
7905af2d 112 e->e_sendqueue->q_status = "5.4.6";
6acfa498 113 return;
779597d8 114 }
b3cbe40f 115
2eb74b19
EA
116 /*
117 ** Do sender deletion.
118 **
119 ** If the sender has the QQUEUEUP flag set, skip this.
120 ** This can happen if the name server is hosed when you
121 ** are trying to send mail. The result is that the sender
122 ** is instantiated in the queue as a recipient.
123 */
124
80ec5253
EA
125 if (!bitset(EF_METOO, e->e_flags) &&
126 !bitset(QQUEUEUP, e->e_from.q_flags))
b3cbe40f 127 {
6acfa498 128 if (tTd(13, 5))
779597d8 129 {
6acfa498
EA
130 printf("sendall: QDONTSEND ");
131 printaddr(&e->e_from, FALSE);
779597d8 132 }
6acfa498 133 e->e_from.q_flags |= QDONTSEND;
f8c2f9fd 134 (void) recipient(&e->e_from, &e->e_sendqueue, 0, e);
b3cbe40f 135 }
e6b0a75b 136
1d303d98
EA
137# ifdef QUEUE
138 if ((mode == SM_QUEUE || mode == SM_FORK ||
139 (mode != SM_VERIFY && SuperSafe)) &&
140 !bitset(EF_INQUEUE, e->e_flags))
141 {
142 /* be sure everything is instantiated in the queue */
143 queueup(e, TRUE, mode == SM_QUEUE);
144 }
145#endif /* QUEUE */
146
147 switch (mode)
148 {
149 case SM_VERIFY:
150 Verbose = TRUE;
151 break;
152
153 case SM_QUEUE:
154 queueonly:
155 e->e_flags |= EF_INQUEUE|EF_KEEPQUEUE;
156 return;
157
158 case SM_FORK:
159 if (e->e_xfp != NULL)
160 (void) fflush(e->e_xfp);
161
162# ifdef LOCKF
163 /*
164 ** Since lockf has the interesting semantic that the
165 ** lock is lost when we fork, we have to risk losing
166 ** the lock here by closing before the fork, and then
167 ** trying to get it back in the child.
168 */
169
170 if (e->e_lockfp != NULL)
171 {
172 (void) xfclose(e->e_lockfp, "sendenvelope", "lockfp");
173 e->e_lockfp = NULL;
174 }
175# endif /* LOCKF */
176
177 pid = fork();
178 if (pid < 0)
179 {
180 goto queueonly;
181 }
182 else if (pid > 0)
183 {
184 /* be sure we leave the temp files to our child */
185 e->e_id = e->e_df = NULL;
186# ifndef LOCKF
187 if (e->e_lockfp != NULL)
188 {
189 (void) xfclose(e->e_lockfp, "sendenvelope", "lockfp");
190 e->e_lockfp = NULL;
191 }
192# endif
193
194 /* close any random open files in the envelope */
195 if (e->e_dfp != NULL)
196 {
197 (void) xfclose(e->e_dfp, "sendenvelope", "dfp");
198 e->e_dfp = NULL;
199 }
200 if (e->e_xfp != NULL)
201 {
202 (void) xfclose(e->e_xfp, "sendenvelope", "xfp");
203 e->e_xfp = NULL;
204 }
205 return;
206 }
207
208 /* double fork to avoid zombies */
209 if (fork() > 0)
210 exit(EX_OK);
211
212 /* be sure we are immune from the terminal */
213 disconnect(FALSE, e);
214
215# ifdef LOCKF
216 /*
217 ** Now try to get our lock back.
218 */
219
220 lfd.l_type = F_WRLCK;
221 lfd.l_whence = lfd.l_start = lfd.l_len = 0;
222 e->e_lockfp = fopen(queuename(e, 'q'), "r+");
223 if (e->e_lockfp == NULL ||
224 fcntl(fileno(e->e_lockfp), F_SETLK, &lfd) < 0)
225 {
226 /* oops.... lost it */
227 if (tTd(13, 1))
228 printf("sendenvelope: %s lost lock: lockfp=%x, %s\n",
229 e->e_id, e->e_lockfp, errstring(errno));
230
231# ifdef LOG
232 if (LogLevel > 29)
233 syslog(LOG_NOTICE, "%s: lost lock: %m",
234 e->e_id);
235# endif /* LOG */
236 exit(EX_OK);
237 }
238# endif /* LOCKF */
239
240 /*
241 ** Close any cached connections.
242 **
243 ** We don't send the QUIT protocol because the parent
244 ** still knows about the connection.
245 **
246 ** This should only happen when delivering an error
247 ** message.
248 */
249
250 mci_flush(FALSE, NULL);
251
252 break;
253 }
254
255 /*
256 ** If we haven't fully expanded aliases, do it now
257 */
258
259 if (bitset(EF_VRFYONLY, e->e_flags))
260 {
261 e->e_flags &= ~EF_VRFYONLY;
262 for (q = e->e_sendqueue; q != NULL; q = q->q_next)
263 {
264 extern ADDRESS *recipient();
265
266 if (bitset(QVERIFIED, q->q_flags))
267 recipient(q, &e->e_sendqueue, e);
268 }
269 }
270
1ab402f2 271 /*
6acfa498
EA
272 ** Handle alias owners.
273 **
274 ** We scan up the q_alias chain looking for owners.
275 ** We discard owners that are the same as the return path.
b3cbe40f
EA
276 */
277
6acfa498 278 for (q = e->e_sendqueue; q != NULL; q = q->q_next)
b3cbe40f 279 {
6acfa498 280 register struct address *a;
779597d8 281
6acfa498 282 for (a = q; a != NULL && a->q_owner == NULL; a = a->q_alias)
779597d8 283 continue;
6acfa498
EA
284 if (a != NULL)
285 q->q_owner = a->q_owner;
286
287 if (q->q_owner != NULL &&
288 !bitset(QDONTSEND, q->q_flags) &&
289 strcmp(q->q_owner, e->e_from.q_paddr) == 0)
290 q->q_owner = NULL;
291 }
292
293 owner = "";
294 otherowners = 1;
295 while (owner != NULL && otherowners > 0)
296 {
297 owner = NULL;
298 otherowners = 0;
1bf7c76b 299
6acfa498 300 for (q = e->e_sendqueue; q != NULL; q = q->q_next)
78bbbc48 301 {
6acfa498
EA
302 if (bitset(QDONTSEND, q->q_flags))
303 continue;
779597d8 304
6acfa498
EA
305 if (q->q_owner != NULL)
306 {
307 if (owner == NULL)
308 owner = q->q_owner;
309 else if (owner != q->q_owner)
310 {
311 if (strcmp(owner, q->q_owner) == 0)
312 {
313 /* make future comparisons cheap */
314 q->q_owner = owner;
315 }
316 else
317 {
318 otherowners++;
319 }
320 owner = q->q_owner;
321 }
322 }
323 else
324 {
325 otherowners++;
326 }
1ce944f0
EA
327
328 /*
329 ** If this mailer is expensive, and if we don't
330 ** want to make connections now, just mark these
331 ** addresses and return. This is useful if we
332 ** want to batch connections to reduce load. This
333 ** will cause the messages to be queued up, and a
334 ** daemon will come along to send the messages later.
335 */
336
337 if (bitset(QBADADDR|QQUEUEUP, q->q_flags))
338 continue;
339 if (NoConnect && !Verbose &&
340 bitnset(M_EXPENSIVE, q->q_mailer->m_flags))
341 {
342 q->q_flags |= QQUEUEUP;
343 e->e_to = q->q_paddr;
344 message("queued");
345 if (LogLevel > 8)
346 logdelivery(q->q_mailer, NULL,
347 "queued", NULL,
348 (time_t) 0, e);
349 e->e_to = NULL;
350 }
351 else
352 {
353 somedeliveries = TRUE;
354 }
779597d8
EA
355 }
356
6acfa498 357 if (owner != NULL && otherowners > 0)
b3cbe40f 358 {
04f6f6a9 359 register ENVELOPE *ee;
6acfa498
EA
360 extern HDR *copyheader();
361 extern ADDRESS *copyqueue();
779597d8 362
6acfa498
EA
363 /*
364 ** Split this envelope into two.
365 */
74c5fe7c 366
6acfa498
EA
367 ee = (ENVELOPE *) xalloc(sizeof(ENVELOPE));
368 *ee = *e;
369 ee->e_id = NULL;
370 (void) queuename(ee, '\0');
0df76d69 371
6acfa498
EA
372 if (tTd(13, 1))
373 printf("sendall: split %s into %s\n",
374 e->e_id, ee->e_id);
779597d8 375
6acfa498
EA
376 ee->e_header = copyheader(e->e_header);
377 ee->e_sendqueue = copyqueue(e->e_sendqueue);
378 ee->e_errorqueue = copyqueue(e->e_errorqueue);
f052a727 379 ee->e_flags = e->e_flags & ~(EF_INQUEUE|EF_CLRQUEUE|EF_FATALERRS|EF_SENDRECEIPT|EF_RET_PARAM);
5b4215a7 380 ee->e_flags |= EF_NORECEIPT;
6acfa498
EA
381 setsender(owner, ee, NULL, TRUE);
382 if (tTd(13, 5))
383 {
384 printf("sendall(split): QDONTSEND ");
385 printaddr(&ee->e_from, FALSE);
386 }
387 ee->e_from.q_flags |= QDONTSEND;
388 ee->e_dfp = NULL;
389 ee->e_xfp = NULL;
6acfa498 390 ee->e_errormode = EM_MAIL;
6acfa498
EA
391
392 for (q = e->e_sendqueue; q != NULL; q = q->q_next)
f052a727 393 {
6acfa498 394 if (q->q_owner == owner)
0cf862de 395 {
6acfa498 396 q->q_flags |= QDONTSEND;
0cf862de
EA
397 q->q_flags &= ~QQUEUEUP;
398 }
f052a727 399 }
6acfa498 400 for (q = ee->e_sendqueue; q != NULL; q = q->q_next)
f052a727 401 {
6acfa498 402 if (q->q_owner != owner)
0cf862de 403 {
6acfa498 404 q->q_flags |= QDONTSEND;
0cf862de
EA
405 q->q_flags &= ~QQUEUEUP;
406 }
f052a727
EA
407 else
408 {
409 /* clear DSN parameters */
410 q->q_flags &= ~(QHASNOTIFY|QPINGONSUCCESS);
411 q->q_flags |= QPINGONFAILURE|QPINGONDELAY;
412 }
413 }
e6b0a75b 414
18a81ac0 415 if (mode != SM_VERIFY && bitset(EF_HAS_DF, e->e_flags))
e6b0a75b 416 {
18a81ac0
EA
417 char df1buf[20], df2buf[20];
418
6acfa498 419 ee->e_dfp = NULL;
18a81ac0
EA
420 strcpy(df1buf, queuename(e, 'd'));
421 strcpy(df2buf, queuename(ee, 'd'));
422 if (link(df1buf, df2buf) < 0)
6acfa498
EA
423 {
424 syserr("sendall: link(%s, %s)",
18a81ac0 425 df1buf, df2buf);
6acfa498 426 }
e6b0a75b 427 }
6acfa498
EA
428#ifdef LOG
429 if (LogLevel > 4)
9cc11aa8
EA
430 syslog(LOG_INFO, "%s: clone %s, owner=%s",
431 ee->e_id, e->e_id, owner);
6acfa498 432#endif
04f6f6a9
EA
433 CurEnv = ee;
434 sendenvelope(ee, mode, announcequeueup);
435 dropenvelope(ee);
779597d8 436 }
b3cbe40f
EA
437 }
438
04f6f6a9
EA
439 /*
440 ** Split off envelopes have been sent -- now send original
441 */
442
6acfa498 443 if (owner != NULL)
e6b0a75b 444 {
6acfa498
EA
445 setsender(owner, e, NULL, TRUE);
446 if (tTd(13, 5))
447 {
448 printf("sendall(owner): QDONTSEND ");
449 printaddr(&e->e_from, FALSE);
450 }
451 e->e_from.q_flags |= QDONTSEND;
452 e->e_errormode = EM_MAIL;
5b4215a7 453 e->e_flags |= EF_NORECEIPT;
e6b0a75b 454 }
1ef61b9f 455
1ce944f0
EA
456 /* if nothing to be delivered, just queue up everything */
457 if (!somedeliveries && mode != SM_QUEUE && mode != SM_VERIFY)
458 mode = SM_QUEUE;
459
11024b4c
EA
460 bool oldverbose = Verbose;
461
462 if (splitenv != NULL)
463 {
464 if (tTd(13, 1))
465 {
466 printf("\nsendall: Split queue; remaining queue:\n");
467 printaddr(e->e_sendqueue, TRUE);
468 }
469
470 for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
471 {
472 CurEnv = ee;
473 if (mode != SM_VERIFY)
474 openxscript(ee);
475 sendenvelope(ee, mode);
476 dropenvelope(ee);
477 }
478
479 CurEnv = e;
480 }
481 sendenvelope(e, mode);
482 Verbose = oldverbose;
6acfa498
EA
483}
484
ea07b2d2 485void
11024b4c 486sendenvelope(e, mode)
6acfa498
EA
487 register ENVELOPE *e;
488 char mode;
489{
6acfa498 490 register ADDRESS *q;
11024b4c
EA
491 bool didany;
492
493 /*
494 ** If we have had global, fatal errors, don't bother sending
495 ** the message at all if we are in SMTP mode. Local errors
496 ** (e.g., a single address failing) will still cause the other
497 ** addresses to be sent.
498 */
499
500 if (bitset(EF_FATALERRS, e->e_flags) &&
501 (OpMode == MD_SMTP || OpMode == MD_DAEMON))
502 {
503 e->e_flags |= EF_CLRQUEUE;
504 return;
505 }
f2e44ded 506
ed45aae1 507 /*
6acfa498 508 ** Run through the list and send everything.
0fc3fb21
EA
509 **
510 ** Set EF_GLOBALERRS so that error messages during delivery
511 ** result in returned mail.
ed45aae1
EA
512 */
513
6acfa498 514 e->e_nsent = 0;
0fc3fb21 515 e->e_flags |= EF_GLOBALERRS;
f009d24b 516 didany = FALSE;
69c74bb8 517
69c74bb8 518 /* now run through the queue */
6acfa498 519 for (q = e->e_sendqueue; q != NULL; q = q->q_next)
f2e44ded 520 {
a40faef5 521#if XDEBUG
f9fbda25
EA
522 char wbuf[MAXNAME + 20];
523
524 (void) sprintf(wbuf, "sendall(%s)", q->q_paddr);
525 checkfd012(wbuf);
526#endif
6acfa498 527 if (mode == SM_VERIFY)
1627a785 528 {
6acfa498
EA
529 e->e_to = q->q_paddr;
530 if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
d1c234d8 531 {
58057ca3
EA
532 if (q->q_host != NULL && q->q_host[0] != '\0')
533 message("deliverable: mailer %s, host %s, user %s",
534 q->q_mailer->m_name,
535 q->q_host,
536 q->q_user);
537 else
538 message("deliverable: mailer %s, user %s",
539 q->q_mailer->m_name,
540 q->q_user);
d1c234d8 541 }
6acfa498
EA
542 }
543 else if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
544 {
545# ifdef QUEUE
546 /*
547 ** Checkpoint the send list every few addresses
548 */
549
550 if (e->e_nsent >= CheckpointInterval)
551 {
552 queueup(e, TRUE, FALSE);
553 e->e_nsent = 0;
554 }
555# endif /* QUEUE */
556 (void) deliver(e, q);
f009d24b 557 didany = TRUE;
1627a785 558 }
f2e44ded 559 }
f009d24b
EA
560 if (didany)
561 {
562 e->e_dtime = curtime();
563 e->e_ntries++;
564 }
f2e44ded 565
a40faef5 566#if XDEBUG
f9fbda25
EA
567 checkfd012("end of sendenvelope");
568#endif
569
6acfa498
EA
570 if (mode == SM_FORK)
571 finis();
779597d8
EA
572}
573\f/*
6acfa498
EA
574** DOFORK -- do a fork, retrying a couple of times on failure.
575**
576** This MUST be a macro, since after a vfork we are running
577** two processes on the same stack!!!
b9e44c3d
EA
578**
579** Parameters:
6acfa498 580** none.
b9e44c3d
EA
581**
582** Returns:
6acfa498 583** From a macro??? You've got to be kidding!
b9e44c3d
EA
584**
585** Side Effects:
6acfa498
EA
586** Modifies the ==> LOCAL <== variable 'pid', leaving:
587** pid of child in parent, zero in child.
588** -1 on unrecoverable error.
589**
590** Notes:
591** I'm awfully sorry this looks so awful. That's
592** vfork for you.....
b9e44c3d
EA
593*/
594
6acfa498 595# define NFORKTRIES 5
140717b5
EA
596
597# ifndef FORK
598# define FORK fork
599# endif
67e64653
EA
600
601# define DOFORK(fORKfN) \
602{\
603 register int i;\
604\
11e32817 605 for (i = NFORKTRIES; --i >= 0; )\
67e64653
EA
606 {\
607 pid = fORKfN();\
608 if (pid >= 0)\
609 break;\
11e32817 610 if (i > 0)\
901911f8 611 sleep((unsigned) NFORKTRIES - i);\
67e64653
EA
612 }\
613}
614\f/*
2cf55cb7
EA
615** DOFORK -- simple fork interface to DOFORK.
616**
617** Parameters:
618** none.
619**
620** Returns:
621** pid of child in parent.
622** zero in child.
623** -1 on error.
624**
625** Side Effects:
626** returns twice, once in parent and once in child.
627*/
628
179d940c 629int
2cf55cb7
EA
630dofork()
631{
ea07b2d2 632 register int pid = -1;
2cf55cb7
EA
633
634 DOFORK(fork);
635 return (pid);
636}
637\f/*
6acfa498 638** DELIVER -- Deliver a message to a list of addresses.
e6b0a75b 639**
6acfa498
EA
640** This routine delivers to everyone on the same host as the
641** user on the head of the list. It is clever about mailers
642** that don't handle multiple users. It is NOT guaranteed
643** that it will deliver to all these addresses however -- so
644** deliver should be called once for each address on the
645** list.
e6b0a75b
EA
646**
647** Parameters:
6acfa498
EA
648** e -- the envelope to deliver.
649** firstto -- head of the address list to deliver to.
e6b0a75b
EA
650**
651** Returns:
6acfa498
EA
652** zero -- successfully delivered.
653** else -- some failure, see ExitStat for more info.
e6b0a75b
EA
654**
655** Side Effects:
6acfa498 656** The standard input is passed off to someone.
e6b0a75b
EA
657*/
658
ea07b2d2 659int
6acfa498 660deliver(e, firstto)
30eab7ca 661 register ENVELOPE *e;
6acfa498 662 ADDRESS *firstto;
e6b0a75b 663{
6acfa498
EA
664 char *host; /* host being sent to */
665 char *user; /* user being sent to */
666 char **pvp;
667 register char **mvp;
668 register char *p;
669 register MAILER *m; /* mailer for this recipient */
670 ADDRESS *ctladdr;
671 register MCI *mci;
672 register ADDRESS *to = firstto;
673 bool clever = FALSE; /* running user smtp to this mailer */
ea07b2d2 674 ADDRESS *tochain = NULL; /* users chain in this mailer call */
6acfa498
EA
675 int rcode; /* response code */
676 char *firstsig; /* signature of firstto */
ea07b2d2 677 int pid = -1;
6acfa498 678 char *curhost;
3500a891 679 time_t xstart;
6acfa498
EA
680 int mpvect[2];
681 int rpvect[2];
682 char *pv[MAXPV+1];
683 char tobuf[TOBUFSIZE]; /* text line of to people */
8446c922
EA
684 char buf[MAXNAME + 1];
685 char rpathbuf[MAXNAME + 1]; /* translated return path */
6acfa498 686 extern int checkcompat();
179d940c 687 extern void markfailure __P((ENVELOPE *, ADDRESS *, MCI *, int));
e6b0a75b 688
6acfa498
EA
689 errno = 0;
690 if (!ForceMail && bitset(QDONTSEND|QPSEUDO, to->q_flags))
691 return (0);
2ae0e0ed 692
efe7f723 693#if NAMED_BIND
6acfa498 694 /* unless interactive, try twice, over a minute */
198d9e9c
EA
695 if (OpMode == MD_DAEMON || OpMode == MD_SMTP)
696 {
6acfa498
EA
697 _res.retrans = 30;
698 _res.retry = 2;
699 }
700#endif
1ab402f2 701
6acfa498
EA
702 m = to->q_mailer;
703 host = to->q_host;
704 CurEnv = e; /* just in case */
0992263e 705 e->e_statmsg = NULL;
fe3849ea 706 SmtpError[0] = '\0';
4c309714 707 xstart = curtime();
6acfa498
EA
708
709 if (tTd(10, 1))
116d2937
EA
710 printf("\n--deliver, id=%s, mailer=%s, host=`%s', first user=`%s'\n",
711 e->e_id, m->m_name, host, to->q_user);
35f14050
EA
712 if (tTd(10, 100))
713 printopenfds(FALSE);
6acfa498 714
6acfa498
EA
715 /*
716 ** Do initial argv setup.
717 ** Insert the mailer name. Notice that $x expansion is
718 ** NOT done on the mailer name. Then, if the mailer has
719 ** a picky -f flag, we insert it as appropriate. This
720 ** code does not check for 'pv' overflow; this places a
721 ** manifest lower limit of 4 for MAXPV.
722 ** The from address rewrite is expected to make
723 ** the address relative to the other end.
724 */
725
726 /* rewrite from address, using rewriting rules */
9e43a19e 727 rcode = EX_OK;
295b05c5
EA
728 if (bitnset(M_UDBENVELOPE, e->e_from.q_mailer->m_flags))
729 p = e->e_sender;
730 else
731 p = e->e_from.q_paddr;
732 (void) strcpy(rpathbuf, remotename(p, m,
9e43a19e
EA
733 RF_SENDERADDR|RF_CANONICAL,
734 &rcode, e));
6acfa498
EA
735 define('g', rpathbuf, e); /* translated return path */
736 define('h', host, e); /* to host */
737 Errors = 0;
738 pvp = pv;
739 *pvp++ = m->m_argv[0];
740
741 /* insert -f or -r flag as appropriate */
742 if (FromFlag && (bitnset(M_FOPT, m->m_flags) || bitnset(M_ROPT, m->m_flags)))
743 {
744 if (bitnset(M_FOPT, m->m_flags))
745 *pvp++ = "-f";
746 else
747 *pvp++ = "-r";
748 *pvp++ = newstr(rpathbuf);
749 }
750
751 /*
752 ** Append the other fixed parts of the argv. These run
753 ** up to the first entry containing "$u". There can only
754 ** be one of these, and there are only a few more slots
755 ** in the pv after it.
756 */
757
758 for (mvp = m->m_argv; (p = *++mvp) != NULL; )
759 {
760 /* can't use strchr here because of sign extension problems */
761 while (*p != '\0')
762 {
763 if ((*p++ & 0377) == MACROEXPAND)
764 {
765 if (*p == 'u')
766 break;
767 }
768 }
769
770 if (*p != '\0')
771 break;
772
773 /* this entry is safe -- go ahead and process it */
832e8a27 774 expand(*mvp, buf, sizeof buf, e);
6acfa498
EA
775 *pvp++ = newstr(buf);
776 if (pvp >= &pv[MAXPV - 3])
777 {
778 syserr("554 Too many parameters to %s before $u", pv[0]);
779 return (-1);
780 }
781 }
782
783 /*
784 ** If we have no substitution for the user name in the argument
785 ** list, we know that we must supply the names otherwise -- and
786 ** SMTP is the answer!!
787 */
788
789 if (*mvp == NULL)
790 {
791 /* running SMTP */
792# ifdef SMTP
793 clever = TRUE;
794 *pvp = NULL;
795# else /* SMTP */
796 /* oops! we don't implement SMTP */
fe3849ea 797 syserr("554 SMTP style mailer not implemented");
7338e3d4 798 return (EX_SOFTWARE);
6acfa498 799# endif /* SMTP */
e6b0a75b 800 }
1ab402f2 801
6acfa498
EA
802 /*
803 ** At this point *mvp points to the argument with $u. We
804 ** run through our address list and append all the addresses
805 ** we can. If we run out of space, do not fret! We can
806 ** always send another copy later.
807 */
808
809 tobuf[0] = '\0';
810 e->e_to = tobuf;
811 ctladdr = NULL;
812 firstsig = hostsignature(firstto->q_mailer, firstto->q_host, e);
813 for (; to != NULL; to = to->q_next)
e6b0a75b 814 {
6acfa498
EA
815 /* avoid sending multiple recipients to dumb mailers */
816 if (tobuf[0] != '\0' && !bitnset(M_MUSER, m->m_flags))
817 break;
30eab7ca 818
6acfa498
EA
819 /* if already sent or not for this host, don't send */
820 if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags) ||
821 to->q_mailer != firstto->q_mailer ||
822 strcmp(hostsignature(to->q_mailer, to->q_host, e), firstsig) != 0)
823 continue;
824
825 /* avoid overflowing tobuf */
826 if (sizeof tobuf < (strlen(to->q_paddr) + strlen(tobuf) + 2))
827 break;
828
829 if (tTd(10, 1))
30eab7ca 830 {
6acfa498
EA
831 printf("\nsend to ");
832 printaddr(to, FALSE);
833 }
30eab7ca 834
6acfa498 835 /* compute effective uid/gid when sending */
2bade550 836 if (bitnset(M_RUNASRCPT, to->q_mailer->m_flags))
c8de5c6d 837 ctladdr = getctladdr(to);
6acfa498 838
bdd1eb9a
EA
839 if (tTd(10, 2))
840 {
841 printf("ctladdr=");
842 printaddr(ctladdr, FALSE);
843 }
844
6acfa498
EA
845 user = to->q_user;
846 e->e_to = to->q_paddr;
847 if (tTd(10, 5))
848 {
849 printf("deliver: QDONTSEND ");
850 printaddr(to, FALSE);
30eab7ca 851 }
6acfa498 852 to->q_flags |= QDONTSEND;
30eab7ca 853
6acfa498
EA
854 /*
855 ** Check to see that these people are allowed to
856 ** talk to each other.
857 */
858
859 if (m->m_maxsize != 0 && e->e_msgsize > m->m_maxsize)
860 {
c7a0eaaf 861 e->e_flags |= EF_NO_BODY_RETN;
179d940c 862 to->q_status = "5.2.3";
6acfa498 863 usrerr("552 Message is too large; %ld bytes max", m->m_maxsize);
3500a891 864 giveresponse(EX_UNAVAILABLE, m, NULL, ctladdr, xstart, e);
6acfa498
EA
865 continue;
866 }
fdcfa6b8
EA
867#if NAMED_BIND
868 h_errno = 0;
869#endif
6acfa498
EA
870 rcode = checkcompat(to, e);
871 if (rcode != EX_OK)
872 {
a542cc51 873 markfailure(e, to, NULL, rcode);
3500a891 874 giveresponse(rcode, m, NULL, ctladdr, xstart, e);
6acfa498
EA
875 continue;
876 }
877
878 /*
879 ** Strip quote bits from names if the mailer is dumb
880 ** about them.
881 */
882
883 if (bitnset(M_STRIPQ, m->m_flags))
884 {
885 stripquotes(user);
886 stripquotes(host);
887 }
888
889 /* hack attack -- delivermail compatibility */
890 if (m == ProgMailer && *user == '|')
891 user++;
892
893 /*
894 ** If an error message has already been given, don't
895 ** bother to send to this address.
896 **
897 ** >>>>>>>>>> This clause assumes that the local mailer
898 ** >> NOTE >> cannot do any further aliasing; that
899 ** >>>>>>>>>> function is subsumed by sendmail.
900 */
901
902 if (bitset(QBADADDR|QQUEUEUP, to->q_flags))
903 continue;
904
905 /* save statistics.... */
906 markstats(e, to);
907
908 /*
909 ** See if this user name is "special".
910 ** If the user name has a slash in it, assume that this
911 ** is a file -- send it off without further ado. Note
912 ** that this type of addresses is not processed along
913 ** with the others, so we fudge on the To person.
914 */
915
376c6f37 916 if (strcmp(m->m_mailer, "[FILE]") == 0)
6acfa498 917 {
b6f25ddb 918 rcode = mailfile(user, ctladdr, SFF_CREAT, e);
3500a891 919 giveresponse(rcode, m, NULL, ctladdr, xstart, e);
f8c2f9fd 920 e->e_nsent++;
6acfa498 921 if (rcode == EX_OK)
f8c2f9fd 922 {
6acfa498 923 to->q_flags |= QSENT;
f8c2f9fd
EA
924 if (bitnset(M_LOCALMAILER, m->m_flags) &&
925 (e->e_receiptto != NULL ||
926 bitset(QPINGONSUCCESS, to->q_flags)))
927 {
126c1099 928 to->q_flags |= QDELIVERED;
7905af2d 929 to->q_status = "2.1.5";
f8c2f9fd
EA
930 fprintf(e->e_xfp, "%s... Successfully delivered\n",
931 to->q_paddr);
932 }
933 }
68d9129a 934 to->q_statdate = curtime();
6acfa498
EA
935 continue;
936 }
937
938 /*
939 ** Address is verified -- add this user to mailer
940 ** argv, and add it to the print list of recipients.
941 */
942
943 /* link together the chain of recipients */
944 to->q_tchain = tochain;
945 tochain = to;
946
947 /* create list of users for error messages */
948 (void) strcat(tobuf, ",");
949 (void) strcat(tobuf, to->q_paddr);
950 define('u', user, e); /* to user */
ce4c39a9
EA
951 p = to->q_home;
952 if (p == NULL && ctladdr != NULL)
953 p = ctladdr->q_home;
954 define('z', p, e); /* user's home */
6acfa498
EA
955
956 /*
957 ** Expand out this user into argument list.
958 */
959
960 if (!clever)
961 {
832e8a27 962 expand(*mvp, buf, sizeof buf, e);
6acfa498
EA
963 *pvp++ = newstr(buf);
964 if (pvp >= &pv[MAXPV - 2])
965 {
966 /* allow some space for trailing parms */
967 break;
968 }
969 }
e6b0a75b 970 }
1ab402f2 971
6acfa498
EA
972 /* see if any addresses still exist */
973 if (tobuf[0] == '\0')
974 {
975 define('g', (char *) NULL, e);
976 return (0);
977 }
978
979 /* print out messages as full list */
980 e->e_to = tobuf + 1;
981
982 /*
983 ** Fill out any parameters after the $u parameter.
984 */
985
986 while (!clever && *++mvp != NULL)
987 {
832e8a27 988 expand(*mvp, buf, sizeof buf, e);
6acfa498
EA
989 *pvp++ = newstr(buf);
990 if (pvp >= &pv[MAXPV])
991 syserr("554 deliver: pv overflow after $u for %s", pv[0]);
992 }
993 *pvp++ = NULL;
994
995 /*
996 ** Call the mailer.
997 ** The argument vector gets built, pipes
998 ** are created as necessary, and we fork & exec as
999 ** appropriate.
1000 ** If we are running SMTP, we just need to clean up.
1001 */
e6b0a75b 1002
c8de5c6d 1003 /*XXX this seems a bit wierd */
0aeae945 1004 if (ctladdr == NULL && m != ProgMailer && m != FileMailer &&
a773ed15 1005 bitset(QGOODUID, e->e_from.q_flags))
c8de5c6d
EA
1006 ctladdr = &e->e_from;
1007
efe7f723 1008#if NAMED_BIND
6acfa498
EA
1009 if (ConfigLevel < 2)
1010 _res.options &= ~(RES_DEFNAMES | RES_DNSRCH); /* XXX */
1011#endif
779597d8 1012
9678c96d 1013 if (tTd(11, 1))
b3cbe40f 1014 {
857afefe 1015 printf("openmailer:");
6acfa498 1016 printav(pv);
b3cbe40f 1017 }
d829793b 1018 errno = 0;
fdcfa6b8
EA
1019#if NAMED_BIND
1020 h_errno = 0;
1021#endif
779597d8 1022
a542cc51 1023 CurHostName = NULL;
57c97d4a 1024
1ab402f2
EA
1025 /*
1026 ** Deal with the special case of mail handled through an IPC
1027 ** connection.
1028 ** In this case we don't actually fork. We must be
1029 ** running SMTP for this to work. We will return a
1030 ** zero pid to indicate that we are running IPC.
5463e94d 1031 ** We also handle a debug version that just talks to stdin/out.
1ab402f2
EA
1032 */
1033
6acfa498 1034 curhost = NULL;
649a3283 1035 SmtpPhase = NULL;
fe3849ea 1036 mci = NULL;
6acfa498 1037
a40faef5 1038#if XDEBUG
061a3d08
EA
1039 {
1040 char wbuf[MAXLINE];
1041
1042 /* make absolutely certain 0, 1, and 2 are in use */
1043 sprintf(wbuf, "%s... openmailer(%s)", e->e_to, m->m_name);
1044 checkfd012(wbuf);
1045 }
1046#endif
1047
e3c84ea8
EA
1048 /* check for 8-bit available */
1049 if (bitset(EF_HAS8BIT, e->e_flags) &&
1050 bitnset(M_7BITS, m->m_flags) &&
a5386d1b
EA
1051 (!bitset(MM_MIME8BIT, MimeMode) ||
1052 bitset(EF_DONT_MIME, e->e_flags)))
e3c84ea8
EA
1053 {
1054 usrerr("554 Cannot send 8-bit data to 7-bit destination");
1055 rcode = EX_DATAERR;
4e1c01f9 1056 e->e_status = "5.6.3";
e3c84ea8
EA
1057 goto give_up;
1058 }
1059
5463e94d
EA
1060 /* check for Local Person Communication -- not for mortals!!! */
1061 if (strcmp(m->m_mailer, "[LPC]") == 0)
1062 {
f2e44ded 1063 mci = (MCI *) xalloc(sizeof *mci);
3eb4fac4 1064 bzero((char *) mci, sizeof *mci);
2ae0e0ed
EA
1065 mci->mci_in = stdin;
1066 mci->mci_out = stdout;
f2e44ded 1067 mci->mci_state = clever ? MCIS_OPENING : MCIS_OPEN;
e62e1144 1068 mci->mci_mailer = m;
5463e94d 1069 }
f2e44ded
EA
1070 else if (strcmp(m->m_mailer, "[IPC]") == 0 ||
1071 strcmp(m->m_mailer, "[TCP]") == 0)
1ab402f2 1072 {
140717b5 1073#ifdef DAEMON
7e70d3c8 1074 register int i;
ea07b2d2 1075 register u_short port = 0;
1ab402f2 1076
7bdee402
EA
1077 if (pv[0] == NULL || pv[1] == NULL || pv[1][0] == '\0')
1078 {
1079 syserr("null host name for %s mailer", m->m_mailer);
1080 rcode = EX_CONFIG;
1081 goto give_up;
1082 }
1083
6acfa498
EA
1084 CurHostName = pv[1];
1085 curhost = hostsignature(m, pv[1], e);
f2e44ded 1086
f2b8376e
EA
1087 if (curhost == NULL || curhost[0] == '\0')
1088 {
7bdee402 1089 syserr("null host signature for %s", pv[1]);
37750f57 1090 rcode = EX_CONFIG;
6acfa498 1091 goto give_up;
f2b8376e
EA
1092 }
1093
1ab402f2 1094 if (!clever)
f2b8376e 1095 {
b6edea3d 1096 syserr("554 non-clever IPC");
fe3849ea 1097 rcode = EX_CONFIG;
6acfa498 1098 goto give_up;
f2b8376e 1099 }
6acfa498 1100 if (pv[2] != NULL)
26b672df
EA
1101 {
1102 port = htons(atoi(pv[2]));
1103 if (port == 0)
1104 {
1105 struct servent *sp = getservbyname(pv[2], "tcp");
1106
1107 if (sp == NULL)
1108 syserr("Service %s unknown", pv[2]);
1109 else
1110 port = sp->s_port;
1111 }
1112 }
6acfa498 1113tryhost:
7e70d3c8 1114 while (*curhost != '\0')
e2abd3be 1115 {
7e70d3c8 1116 register char *p;
8446c922 1117 static char hostbuf[MAXNAME + 1];
7e70d3c8
EA
1118
1119 /* pull the next host from the signature */
1120 p = strchr(curhost, ':');
1121 if (p == NULL)
1122 p = &curhost[strlen(curhost)];
fe3849ea
EA
1123 if (p == curhost)
1124 {
1125 syserr("deliver: null host name in signature");
7c40218a 1126 curhost++;
fe3849ea
EA
1127 continue;
1128 }
7e70d3c8
EA
1129 strncpy(hostbuf, curhost, p - curhost);
1130 hostbuf[p - curhost] = '\0';
1131 if (*p != '\0')
1132 p++;
1133 curhost = p;
1134
8657d05f 1135 /* see if we already know that this host is fried */
7e70d3c8
EA
1136 CurHostName = hostbuf;
1137 mci = mci_get(hostbuf, m);
f2e44ded 1138 if (mci->mci_state != MCIS_CLOSED)
237bda52
EA
1139 {
1140 if (tTd(11, 1))
1141 {
1142 printf("openmailer: ");
deff97fd 1143 mci_dump(mci, FALSE);
237bda52 1144 }
322eceee 1145 CurHostName = mci->mci_host;
5f14cfca
EA
1146 message("Using cached connection to %s via %s...",
1147 hostbuf, m->m_name);
6acfa498 1148 break;
237bda52 1149 }
e62e1144 1150 mci->mci_mailer = m;
f2e44ded
EA
1151 if (mci->mci_exitstat != EX_OK)
1152 continue;
1153
1154 /* try the connection */
7e70d3c8 1155 setproctitle("%s %s: %s", e->e_id, hostbuf, "user open");
5f14cfca 1156 message("Connecting to %s via %s...",
7e70d3c8
EA
1157 hostbuf, m->m_name);
1158 i = makeconnection(hostbuf, port, mci,
f2e44ded
EA
1159 bitnset(M_SECURE_PORT, m->m_flags));
1160 mci->mci_exitstat = i;
1161 mci->mci_errno = errno;
efe7f723 1162#if NAMED_BIND
8e5c6745
EA
1163 mci->mci_herrno = h_errno;
1164#endif
f2e44ded 1165 if (i == EX_OK)
e2abd3be 1166 {
f2e44ded
EA
1167 mci->mci_state = MCIS_OPENING;
1168 mci_cache(mci);
8e5c6745
EA
1169 if (TrafficLogFile != NULL)
1170 fprintf(TrafficLogFile, "%05d == CONNECT %s\n",
1171 getpid(), hostbuf);
f2e44ded 1172 break;
e2abd3be 1173 }
f2e44ded
EA
1174 else if (tTd(11, 1))
1175 printf("openmailer: makeconnection => stat=%d, errno=%d\n",
1176 i, errno);
1177
2ae0e0ed
EA
1178 /* enter status of this host */
1179 setstat(i);
fe3849ea
EA
1180
1181 /* should print some message here for -v mode */
1182 }
1183 if (mci == NULL)
1184 {
1185 syserr("deliver: no host name");
1186 rcode = EX_OSERR;
1187 goto give_up;
1ea752a1 1188 }
3eb4fac4 1189 mci->mci_pid = 0;
f2e44ded 1190#else /* no DAEMON */
b6edea3d 1191 syserr("554 openmailer: no IPC");
237bda52
EA
1192 if (tTd(11, 1))
1193 printf("openmailer: NULL\n");
fe3849ea
EA
1194 rcode = EX_UNAVAILABLE;
1195 goto give_up;
f2e44ded 1196#endif /* DAEMON */
1ab402f2 1197 }
f2e44ded 1198 else
b3cbe40f 1199 {
c1dc4fb9
EA
1200 /* flush any expired connections */
1201 (void) mci_scan(NULL);
1202
1203 /* announce the connection to verbose listeners */
5f14cfca
EA
1204 if (host == NULL || host[0] == '\0')
1205 message("Connecting to %s...", m->m_name);
1206 else
1207 message("Connecting to %s via %s...", host, m->m_name);
8e5c6745 1208 if (TrafficLogFile != NULL)
4a101ce5 1209 {
8e5c6745 1210 char **av;
f22c6db0 1211
8e5c6745
EA
1212 fprintf(TrafficLogFile, "%05d === EXEC", getpid());
1213 for (av = pv; *av != NULL; av++)
1214 fprintf(TrafficLogFile, " %s", *av);
1215 fprintf(TrafficLogFile, "\n");
4a101ce5
EA
1216 }
1217
f2e44ded
EA
1218 /* create a pipe to shove the mail through */
1219 if (pipe(mpvect) < 0)
1220 {
f22c6db0
EA
1221 syserr("%s... openmailer(%s): pipe (to mailer)",
1222 e->e_to, m->m_name);
237bda52
EA
1223 if (tTd(11, 1))
1224 printf("openmailer: NULL\n");
6acfa498
EA
1225 rcode = EX_OSERR;
1226 goto give_up;
f2e44ded 1227 }
e6b0a75b 1228
f2e44ded
EA
1229 /* if this mailer speaks smtp, create a return pipe */
1230 if (clever && pipe(rpvect) < 0)
1231 {
f22c6db0
EA
1232 syserr("%s... openmailer(%s): pipe (from mailer)",
1233 e->e_to, m->m_name);
f2e44ded
EA
1234 (void) close(mpvect[0]);
1235 (void) close(mpvect[1]);
237bda52
EA
1236 if (tTd(11, 1))
1237 printf("openmailer: NULL\n");
6acfa498
EA
1238 rcode = EX_OSERR;
1239 goto give_up;
f2e44ded 1240 }
e6b0a75b 1241
f2e44ded
EA
1242 /*
1243 ** Actually fork the mailer process.
1244 ** DOFORK is clever about retrying.
1245 **
1246 ** Dispose of SIGCHLD signal catchers that may be laying
1247 ** around so that endmail will get it.
1248 */
1ab402f2 1249
f2e44ded
EA
1250 if (e->e_xfp != NULL)
1251 (void) fflush(e->e_xfp); /* for debugging */
1252 (void) fflush(stdout);
1cc8903f 1253# ifdef SIGCHLD
39270cfd 1254 (void) setsignal(SIGCHLD, SIG_DFL);
f3d8f6d6 1255# endif /* SIGCHLD */
f2e44ded
EA
1256 DOFORK(FORK);
1257 /* pid is set by DOFORK */
1258 if (pid < 0)
e6b0a75b 1259 {
f2e44ded 1260 /* failure */
f22c6db0
EA
1261 syserr("%s... openmailer(%s): cannot fork",
1262 e->e_to, m->m_name);
f2e44ded
EA
1263 (void) close(mpvect[0]);
1264 (void) close(mpvect[1]);
1265 if (clever)
1266 {
1267 (void) close(rpvect[0]);
1268 (void) close(rpvect[1]);
1269 }
237bda52
EA
1270 if (tTd(11, 1))
1271 printf("openmailer: NULL\n");
6acfa498
EA
1272 rcode = EX_OSERR;
1273 goto give_up;
e6b0a75b 1274 }
f2e44ded
EA
1275 else if (pid == 0)
1276 {
1277 int i;
f62b79ae 1278 int saveerrno;
33a75b9a 1279 struct stat stb;
f2e44ded 1280 extern int DtableSize;
f2ba91d2 1281
2c2b6557 1282 if (e->e_lockfp != NULL)
633a3177 1283 (void) close(fileno(e->e_lockfp));
2c2b6557 1284
f2e44ded 1285 /* child -- set up input & exec mailer */
39270cfd
EA
1286 (void) setsignal(SIGINT, SIG_IGN);
1287 (void) setsignal(SIGHUP, SIG_IGN);
1288 (void) setsignal(SIGTERM, SIG_DFL);
49086753 1289
7af42ad2 1290 if (m != FileMailer || stat(tochain->q_user, &stb) < 0)
33a75b9a
EA
1291 stb.st_mode = 0;
1292
dcc15ef5
EA
1293 /* tweak niceness */
1294 if (m->m_nice != 0)
1295 nice(m->m_nice);
1296
33a75b9a 1297 /* reset group id */
1ff27f9b 1298 if (bitnset(M_SPECIFIC_UID, m->m_flags))
1ff27f9b 1299 (void) setgid(m->m_gid);
33a75b9a
EA
1300 else if (bitset(S_ISGID, stb.st_mode))
1301 (void) setgid(stb.st_gid);
1302 else if (ctladdr != NULL && ctladdr->q_gid != 0)
f5195abb
EA
1303 {
1304 (void) initgroups(ctladdr->q_ruser?
1305 ctladdr->q_ruser: ctladdr->q_user,
1306 ctladdr->q_gid);
1307 (void) setgid(ctladdr->q_gid);
f5195abb 1308 }
1ff27f9b 1309 else
8d6e073f 1310 {
f5195abb
EA
1311 (void) initgroups(DefUser, DefGid);
1312 if (m->m_gid == 0)
94d9df0e 1313 (void) setgid(DefGid);
f5195abb
EA
1314 else
1315 (void) setgid(m->m_gid);
33a75b9a
EA
1316 }
1317
1318 /* reset user id */
1319 if (bitnset(M_SPECIFIC_UID, m->m_flags))
1320 (void) setuid(m->m_uid);
1321 else if (bitset(S_ISUID, stb.st_mode))
1322 (void) setuid(stb.st_uid);
1323 else if (ctladdr != NULL && ctladdr->q_uid != 0)
1324 (void) setuid(ctladdr->q_uid);
1325 else
1326 {
f5195abb 1327 if (m->m_uid == 0)
8d6e073f 1328 (void) setuid(DefUid);
8d6e073f 1329 else
f5195abb 1330 (void) setuid(m->m_uid);
8d6e073f
EA
1331 }
1332
1333 if (tTd(11, 2))
1334 printf("openmailer: running as r/euid=%d/%d\n",
1335 getuid(), geteuid());
1336
6f5db107
EA
1337 /* move into some "safe" directory */
1338 if (m->m_execdir != NULL)
1339 {
1340 char *p, *q;
8446c922 1341 char buf[MAXLINE + 1];
6f5db107
EA
1342
1343 for (p = m->m_execdir; p != NULL; p = q)
1344 {
1345 q = strchr(p, ':');
1346 if (q != NULL)
1347 *q = '\0';
832e8a27 1348 expand(p, buf, sizeof buf, e);
6f5db107
EA
1349 if (q != NULL)
1350 *q++ = ':';
1351 if (tTd(11, 20))
1352 printf("openmailer: trydir %s\n",
1353 buf);
1354 if (buf[0] != '\0' && chdir(buf) >= 0)
1355 break;
1356 }
1357 }
1358
f2e44ded
EA
1359 /* arrange to filter std & diag output of command */
1360 if (clever)
1361 {
1362 (void) close(rpvect[0]);
4a101ce5
EA
1363 if (dup2(rpvect[1], STDOUT_FILENO) < 0)
1364 {
f22c6db0
EA
1365 syserr("%s... openmailer(%s): cannot dup pipe %d for stdout",
1366 e->e_to, m->m_name, rpvect[1]);
4a101ce5
EA
1367 _exit(EX_OSERR);
1368 }
f2e44ded
EA
1369 (void) close(rpvect[1]);
1370 }
52f56f58
EA
1371 else if (OpMode == MD_SMTP || OpMode == MD_DAEMON ||
1372 HoldErrs || DisConnected)
f2e44ded
EA
1373 {
1374 /* put mailer output in transcript */
4a101ce5
EA
1375 if (dup2(fileno(e->e_xfp), STDOUT_FILENO) < 0)
1376 {
f22c6db0
EA
1377 syserr("%s... openmailer(%s): cannot dup xscript %d for stdout",
1378 e->e_to, m->m_name,
4a101ce5
EA
1379 fileno(e->e_xfp));
1380 _exit(EX_OSERR);
1381 }
1382 }
1383 if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0)
1384 {
f22c6db0
EA
1385 syserr("%s... openmailer(%s): cannot dup stdout for stderr",
1386 e->e_to, m->m_name);
4a101ce5 1387 _exit(EX_OSERR);
f2e44ded 1388 }
49086753 1389
f2e44ded
EA
1390 /* arrange to get standard input */
1391 (void) close(mpvect[1]);
d74803dd 1392 if (dup2(mpvect[0], STDIN_FILENO) < 0)
208e82d2 1393 {
f22c6db0
EA
1394 syserr("%s... openmailer(%s): cannot dup pipe %d for stdin",
1395 e->e_to, m->m_name, mpvect[0]);
f2e44ded 1396 _exit(EX_OSERR);
208e82d2 1397 }
f2e44ded 1398 (void) close(mpvect[0]);
7338e3d4 1399
f2e44ded
EA
1400 /* arrange for all the files to be closed */
1401 for (i = 3; i < DtableSize; i++)
1402 {
1403 register int j;
8d6e073f 1404
f2e44ded 1405 if ((j = fcntl(i, F_GETFD, 0)) != -1)
8d6e073f 1406 (void) fcntl(i, F_SETFD, j | 1);
f2e44ded 1407 }
1ab402f2 1408
53d9380f
EA
1409 /* run disconnected from terminal */
1410 (void) setsid();
1411
f2e44ded 1412 /* try to execute the mailer */
05b75231 1413 execve(m->m_mailer, (ARGV_T) pv, (ARGV_T) UserEnviron);
f62b79ae 1414 saveerrno = errno;
f2e44ded 1415 syserr("Cannot exec %s", m->m_mailer);
2bade550
EA
1416 if (bitnset(M_LOCALMAILER, m->m_flags) ||
1417 transienterror(saveerrno))
55b12947 1418 _exit(EX_OSERR);
f2e44ded
EA
1419 _exit(EX_UNAVAILABLE);
1420 }
1421
1422 /*
1423 ** Set up return value.
1424 */
1425
1426 mci = (MCI *) xalloc(sizeof *mci);
3eb4fac4 1427 bzero((char *) mci, sizeof *mci);
f2e44ded
EA
1428 mci->mci_mailer = m;
1429 mci->mci_state = clever ? MCIS_OPENING : MCIS_OPEN;
3eb4fac4 1430 mci->mci_pid = pid;
f2e44ded
EA
1431 (void) close(mpvect[0]);
1432 mci->mci_out = fdopen(mpvect[1], "w");
e9d81da2
EA
1433 if (mci->mci_out == NULL)
1434 {
1435 syserr("deliver: cannot create mailer output channel, fd=%d",
1436 mpvect[1]);
1437 (void) close(mpvect[1]);
1438 if (clever)
1439 {
1440 (void) close(rpvect[0]);
1441 (void) close(rpvect[1]);
1442 }
1443 rcode = EX_OSERR;
1444 goto give_up;
1445 }
f2e44ded
EA
1446 if (clever)
1447 {
1448 (void) close(rpvect[1]);
1449 mci->mci_in = fdopen(rpvect[0], "r");
e9d81da2
EA
1450 if (mci->mci_in == NULL)
1451 {
1452 syserr("deliver: cannot create mailer input channel, fd=%d",
1453 mpvect[1]);
1454 (void) close(rpvect[0]);
1455 fclose(mci->mci_out);
1456 mci->mci_out = NULL;
1457 rcode = EX_OSERR;
1458 goto give_up;
1459 }
f2e44ded
EA
1460 }
1461 else
1462 {
1463 mci->mci_flags |= MCIF_TEMP;
1464 mci->mci_in = NULL;
4287d84d 1465 }
b3cbe40f
EA
1466 }
1467
6acfa498
EA
1468 /*
1469 ** If we are in SMTP opening state, send initial protocol.
1470 */
1471
1472 if (clever && mci->mci_state != MCIS_CLOSED)
1473 {
1474 smtpinit(m, mci, e);
1475 }
f900f13b
EA
1476
1477 if (bitset(EF_HAS8BIT, e->e_flags) && bitnset(M_7BITS, m->m_flags))
1478 mci->mci_flags |= MCIF_CVT8TO7;
1479 else
1480 mci->mci_flags &= ~MCIF_CVT8TO7;
1481
6acfa498
EA
1482 if (tTd(11, 1))
1483 {
1484 printf("openmailer: ");
deff97fd 1485 mci_dump(mci, FALSE);
6acfa498
EA
1486 }
1487
1488 if (mci->mci_state != MCIS_OPEN)
1489 {
1490 /* couldn't open the mailer */
1491 rcode = mci->mci_exitstat;
1492 errno = mci->mci_errno;
efe7f723 1493#if NAMED_BIND
8e5c6745
EA
1494 h_errno = mci->mci_herrno;
1495#endif
6acfa498
EA
1496 if (rcode == EX_OK)
1497 {
1498 /* shouldn't happen */
1499 syserr("554 deliver: rcode=%d, mci_state=%d, sig=%s",
1500 rcode, mci->mci_state, firstsig);
1501 rcode = EX_SOFTWARE;
1502 }
c7a0eaaf 1503 else if (curhost != NULL && *curhost != '\0')
e80c91fc
EA
1504 {
1505 /* try next MX site */
1506 goto tryhost;
1507 }
6acfa498
EA
1508 }
1509 else if (!clever)
1510 {
1511 /*
1512 ** Format and send message.
1513 */
1514
23fafb99 1515 putfromline(mci, e);
51d448e5
EA
1516 (*e->e_puthdr)(mci, e->e_header, e);
1517 (*e->e_putbody)(mci, e, NULL);
6acfa498
EA
1518
1519 /* get the exit status */
1520 rcode = endmailer(mci, e, pv);
1521 }
1522 else
1523#ifdef SMTP
1524 {
1525 /*
1526 ** Send the MAIL FROM: protocol
1527 */
1528
1529 rcode = smtpmailfrom(m, mci, e);
1530 if (rcode == EX_OK)
1531 {
1532 register char *t = tobuf;
1533 register int i;
1534
1535 /* send the recipient list */
1536 tobuf[0] = '\0';
1537 for (to = tochain; to != NULL; to = to->q_tchain)
1538 {
1539 e->e_to = to->q_paddr;
1540 if ((i = smtprcpt(to, m, mci, e)) != EX_OK)
1541 {
a542cc51 1542 markfailure(e, to, mci, i);
3500a891 1543 giveresponse(i, m, mci, ctladdr, xstart, e);
6acfa498
EA
1544 }
1545 else
1546 {
1547 *t++ = ',';
1548 for (p = to->q_paddr; *p; *t++ = *p++)
1549 continue;
51d3cbf1 1550 *t = '\0';
6acfa498
EA
1551 }
1552 }
1553
1554 /* now send the data */
1555 if (tobuf[0] == '\0')
1556 {
1557 rcode = EX_OK;
1558 e->e_to = NULL;
1559 if (bitset(MCIF_CACHED, mci->mci_flags))
1560 smtprset(m, mci, e);
1561 }
1562 else
1563 {
1564 e->e_to = tobuf + 1;
1565 rcode = smtpdata(m, mci, e);
1566 }
1567
1568 /* now close the connection */
1569 if (!bitset(MCIF_CACHED, mci->mci_flags))
1570 smtpquit(m, mci, e);
1571 }
95203269 1572 if (rcode != EX_OK && curhost != NULL && *curhost != '\0')
6acfa498
EA
1573 {
1574 /* try next MX site */
1575 goto tryhost;
1576 }
1577 }
1578#else /* not SMTP */
1579 {
1580 syserr("554 deliver: need SMTP compiled to use clever mailer");
1581 rcode = EX_CONFIG;
1582 goto give_up;
1583 }
1584#endif /* SMTP */
efe7f723 1585#if NAMED_BIND
6acfa498
EA
1586 if (ConfigLevel < 2)
1587 _res.options |= RES_DEFNAMES | RES_DNSRCH; /* XXX */
1588#endif
1589
1590 /* arrange a return receipt if requested */
fe3849ea
EA
1591 if (rcode == EX_OK && e->e_receiptto != NULL &&
1592 bitnset(M_LOCALMAILER, m->m_flags))
6acfa498
EA
1593 {
1594 e->e_flags |= EF_SENDRECEIPT;
1595 /* do we want to send back more info? */
1596 }
1597
1598 /*
1599 ** Do final status disposal.
1600 ** We check for something in tobuf for the SMTP case.
1601 ** If we got a temporary failure, arrange to queue the
1602 ** addressees.
1603 */
1604
1605 give_up:
1606 if (tobuf[0] != '\0')
3500a891 1607 giveresponse(rcode, m, mci, ctladdr, xstart, e);
6acfa498
EA
1608 for (to = tochain; to != NULL; to = to->q_tchain)
1609 {
1610 if (rcode != EX_OK)
a542cc51 1611 markfailure(e, to, mci, rcode);
c8e44a17 1612 else if (!bitset(QBADADDR|QQUEUEUP, to->q_flags))
6acfa498
EA
1613 {
1614 to->q_flags |= QSENT;
f8c2f9fd 1615 to->q_statdate = curtime();
6acfa498 1616 e->e_nsent++;
68d9129a
EA
1617 if (bitnset(M_LOCALMAILER, m->m_flags) &&
1618 (e->e_receiptto != NULL ||
1619 bitset(QPINGONSUCCESS, to->q_flags)))
fe3849ea 1620 {
126c1099 1621 to->q_flags |= QDELIVERED;
7905af2d 1622 to->q_status = "2.1.5";
fe3849ea
EA
1623 fprintf(e->e_xfp, "%s... Successfully delivered\n",
1624 to->q_paddr);
1625 }
c8e44a17 1626 else if (bitset(QPINGONSUCCESS, to->q_flags) &&
66d16835 1627 bitset(QPRIMARY, to->q_flags) &&
c8e44a17
EA
1628 !bitset(MCIF_DSN, mci->mci_flags))
1629 {
1630 to->q_flags |= QRELAYED;
1631 fprintf(e->e_xfp, "%s... relayed; expect no further notifications\n",
1632 to->q_paddr);
1633 }
6acfa498
EA
1634 }
1635 }
1636
1637 /*
1638 ** Restore state and return.
1639 */
1640
a40faef5 1641#if XDEBUG
061a3d08
EA
1642 {
1643 char wbuf[MAXLINE];
1644
1645 /* make absolutely certain 0, 1, and 2 are in use */
164f3011
EA
1646 sprintf(wbuf, "%s... end of deliver(%s)",
1647 e->e_to == NULL ? "NO-TO-LIST" : e->e_to,
1648 m->m_name);
061a3d08
EA
1649 checkfd012(wbuf);
1650 }
1651#endif
1652
6acfa498
EA
1653 errno = 0;
1654 define('g', (char *) NULL, e);
1655 return (rcode);
1656}
1657\f/*
1658** MARKFAILURE -- mark a failure on a specific address.
1659**
1660** Parameters:
1661** e -- the envelope we are sending.
1662** q -- the address to mark.
a542cc51 1663** mci -- mailer connection information.
6acfa498
EA
1664** rcode -- the code signifying the particular failure.
1665**
1666** Returns:
1667** none.
1668**
1669** Side Effects:
1670** marks the address (and possibly the envelope) with the
1671** failure so that an error will be returned or
1672** the message will be queued, as appropriate.
1673*/
1674
179d940c 1675void
a542cc51 1676markfailure(e, q, mci, rcode)
6acfa498
EA
1677 register ENVELOPE *e;
1678 register ADDRESS *q;
a542cc51 1679 register MCI *mci;
6acfa498
EA
1680 int rcode;
1681{
a542cc51 1682 char *stat = NULL;
6acfa498 1683
26c2fd9b
EA
1684 switch (rcode)
1685 {
1686 case EX_OK:
1687 break;
1688
1689 case EX_TEMPFAIL:
1690 case EX_IOERR:
1691 case EX_OSERR:
6acfa498 1692 q->q_flags |= QQUEUEUP;
26c2fd9b
EA
1693 break;
1694
1695 default:
8e5c6745 1696 q->q_flags |= QBADADDR;
26c2fd9b
EA
1697 break;
1698 }
a542cc51 1699
4e1c01f9 1700 /* find most specific error code possible */
a542cc51
EA
1701 if (q->q_status == NULL && mci != NULL)
1702 q->q_status = mci->mci_status;
4e1c01f9
EA
1703 if (q->q_status == NULL)
1704 q->q_status = e->e_status;
1705 if (q->q_status == NULL)
a542cc51 1706 {
4e1c01f9
EA
1707 switch (rcode)
1708 {
1709 case EX_USAGE:
1710 stat = "5.5.4";
1711 break;
a542cc51 1712
4e1c01f9
EA
1713 case EX_DATAERR:
1714 stat = "5.5.2";
1715 break;
a542cc51 1716
4e1c01f9
EA
1717 case EX_NOUSER:
1718 stat = "5.1.1";
1719 break;
09d45ea9 1720
4e1c01f9
EA
1721 case EX_NOHOST:
1722 stat = "5.1.2";
1723 break;
a542cc51 1724
4e1c01f9
EA
1725 case EX_NOINPUT:
1726 case EX_CANTCREAT:
1727 case EX_NOPERM:
1728 stat = "5.3.0";
1729 break;
a542cc51 1730
4e1c01f9
EA
1731 case EX_UNAVAILABLE:
1732 case EX_SOFTWARE:
1733 case EX_OSFILE:
1734 case EX_PROTOCOL:
1735 case EX_CONFIG:
1736 stat = "5.5.0";
1737 break;
a542cc51 1738
4e1c01f9
EA
1739 case EX_OSERR:
1740 case EX_IOERR:
1741 stat = "4.5.0";
1742 break;
1743
1744 case EX_TEMPFAIL:
1745 stat = "4.2.0";
1746 break;
1747 }
1748 if (stat != NULL)
1749 q->q_status = stat;
a542cc51 1750 }
a542cc51 1751
68d9129a 1752 q->q_statdate = curtime();
429602a4
EA
1753 if (CurHostName != NULL && CurHostName[0] != '\0')
1754 q->q_statmta = newstr(CurHostName);
a542cc51
EA
1755 if (rcode != EX_OK && q->q_rstatus == NULL)
1756 {
1757 char buf[30];
1758
1759 (void) sprintf(buf, "%d", rcode);
1760 q->q_rstatus = newstr(buf);
1761 }
6acfa498
EA
1762}
1763\f/*
1764** ENDMAILER -- Wait for mailer to terminate.
1765**
1766** We should never get fatal errors (e.g., segmentation
1767** violation), so we report those specially. For other
1768** errors, we choose a status message (into statmsg),
1769** and if it represents an error, we print it.
1770**
1771** Parameters:
1772** pid -- pid of mailer.
1773** e -- the current envelope.
1774** pv -- the parameter vector that invoked the mailer
1775** (for error messages).
1776**
1777** Returns:
1778** exit code of mailer.
1779**
1780** Side Effects:
1781** none.
1782*/
1783
179d940c 1784int
6acfa498
EA
1785endmailer(mci, e, pv)
1786 register MCI *mci;
1787 register ENVELOPE *e;
1788 char **pv;
1789{
1790 int st;
1791
1792 /* close any connections */
1793 if (mci->mci_in != NULL)
14809fd5 1794 (void) xfclose(mci->mci_in, mci->mci_mailer->m_name, "mci_in");
6acfa498 1795 if (mci->mci_out != NULL)
14809fd5 1796 (void) xfclose(mci->mci_out, mci->mci_mailer->m_name, "mci_out");
6acfa498
EA
1797 mci->mci_in = mci->mci_out = NULL;
1798 mci->mci_state = MCIS_CLOSED;
49086753 1799
6acfa498
EA
1800 /* in the IPC case there is nothing to wait for */
1801 if (mci->mci_pid == 0)
1802 return (EX_OK);
1803
1804 /* wait for the mailer process to die and collect status */
1805 st = waitfor(mci->mci_pid);
1806 if (st == -1)
b3cbe40f 1807 {
6acfa498
EA
1808 syserr("endmailer %s: wait", pv[0]);
1809 return (EX_SOFTWARE);
2ae0e0ed 1810 }
6acfa498 1811
e3791bb6 1812 if (WIFEXITED(st))
237bda52 1813 {
e3791bb6
EA
1814 /* normal death -- return status */
1815 return (WEXITSTATUS(st));
1816 }
6acfa498 1817
e3791bb6 1818 /* it died a horrid death */
0baa9aea
EA
1819 syserr("451 mailer %s died with signal %o",
1820 mci->mci_mailer->m_name, st);
6acfa498 1821
e3791bb6 1822 /* log the arguments */
c1e6eba2 1823 if (pv != NULL && e->e_xfp != NULL)
e3791bb6
EA
1824 {
1825 register char **av;
6acfa498 1826
e3791bb6
EA
1827 fprintf(e->e_xfp, "Arguments:");
1828 for (av = pv; *av != NULL; av++)
1829 fprintf(e->e_xfp, " %s", *av);
1830 fprintf(e->e_xfp, "\n");
237bda52 1831 }
e6b0a75b 1832
e3791bb6
EA
1833 ExitStat = EX_TEMPFAIL;
1834 return (EX_TEMPFAIL);
b3cbe40f
EA
1835}
1836\f/*
1837** GIVERESPONSE -- Interpret an error response from a mailer
1838**
1839** Parameters:
1840** stat -- the status code from the mailer (high byte
1841** only; core dumps must have been taken care of
1842** already).
c0ae0b24
EA
1843** m -- the mailer info for this mailer.
1844** mci -- the mailer connection info -- can be NULL if the
1845** response is given before the connection is made.
5c18c358
EA
1846** ctladdr -- the controlling address for the recipient
1847** address(es).
3500a891
EA
1848** xstart -- the transaction start time, for computing
1849** transaction delays.
c0ae0b24 1850** e -- the current envelope.
b3cbe40f
EA
1851**
1852** Returns:
29871fef 1853** none.
b3cbe40f
EA
1854**
1855** Side Effects:
d916f0ca 1856** Errors may be incremented.
b3cbe40f 1857** ExitStat may be set.
b3cbe40f
EA
1858*/
1859
179d940c 1860void
3500a891 1861giveresponse(stat, m, mci, ctladdr, xstart, e)
b3cbe40f 1862 int stat;
7338e3d4 1863 register MAILER *m;
c0ae0b24 1864 register MCI *mci;
5c18c358 1865 ADDRESS *ctladdr;
3500a891 1866 time_t xstart;
baa0c390 1867 ENVELOPE *e;
b3cbe40f 1868{
c51d6c4c 1869 register const char *statmsg;
b3cbe40f
EA
1870 extern char *SysExMsg[];
1871 register int i;
a0c75a49 1872 extern int N_SysEx;
baa0c390 1873 char buf[MAXLINE];
b3cbe40f 1874
74c5fe7c
EA
1875 /*
1876 ** Compute status message from code.
1877 */
1878
b3cbe40f 1879 i = stat - EX__BASE;
7338e3d4 1880 if (stat == 0)
4a101ce5 1881 {
7338e3d4 1882 statmsg = "250 Sent";
988a20e2 1883 if (e->e_statmsg != NULL)
4a101ce5 1884 {
988a20e2 1885 (void) sprintf(buf, "%s (%s)", statmsg, e->e_statmsg);
4a101ce5
EA
1886 statmsg = buf;
1887 }
1888 }
7338e3d4
EA
1889 else if (i < 0 || i > N_SysEx)
1890 {
1891 (void) sprintf(buf, "554 unknown mailer error %d", stat);
1892 stat = EX_UNAVAILABLE;
1893 statmsg = buf;
1894 }
baa0c390
EA
1895 else if (stat == EX_TEMPFAIL)
1896 {
2388926b 1897 (void) strcpy(buf, SysExMsg[i] + 1);
efe7f723 1898#if NAMED_BIND
88d7486c 1899 if (h_errno == TRY_AGAIN)
92f2b65e 1900 statmsg = errstring(h_errno+E_DNSBASE);
46f6ec52 1901 else
a0c75a49 1902#endif
46f6ec52 1903 {
88d7486c 1904 if (errno != 0)
88d7486c 1905 statmsg = errstring(errno);
88d7486c
MAN
1906 else
1907 {
46f6ec52 1908#ifdef SMTP
88d7486c 1909 statmsg = SmtpError;
f3d8f6d6 1910#else /* SMTP */
88d7486c 1911 statmsg = NULL;
f3d8f6d6 1912#endif /* SMTP */
88d7486c 1913 }
46f6ec52
EA
1914 }
1915 if (statmsg != NULL && statmsg[0] != '\0')
1916 {
e41c463e 1917 (void) strcat(buf, ": ");
46f6ec52 1918 (void) strcat(buf, statmsg);
baa0c390 1919 }
baa0c390
EA
1920 statmsg = buf;
1921 }
efe7f723 1922#if NAMED_BIND
8e5c6745
EA
1923 else if (stat == EX_NOHOST && h_errno != 0)
1924 {
92f2b65e 1925 statmsg = errstring(h_errno + E_DNSBASE);
1fd465b3 1926 (void) sprintf(buf, "%s (%s)", SysExMsg[i] + 1, statmsg);
8e5c6745
EA
1927 statmsg = buf;
1928 }
1929#endif
b3cbe40f 1930 else
46f6ec52 1931 {
b3cbe40f 1932 statmsg = SysExMsg[i];
2388926b
EA
1933 if (*statmsg++ == ':')
1934 {
1935 (void) sprintf(buf, "%s: %s", statmsg, errstring(errno));
1936 statmsg = buf;
1937 }
46f6ec52 1938 }
7338e3d4
EA
1939
1940 /*
1941 ** Print the message as appropriate
1942 */
1943
baa0c390 1944 if (stat == EX_OK || stat == EX_TEMPFAIL)
fe3849ea
EA
1945 {
1946 extern char MsgBuf[];
1947
b10e0325 1948 message("%s", &statmsg[4]);
fe3849ea
EA
1949 if (stat == EX_TEMPFAIL && e->e_xfp != NULL)
1950 fprintf(e->e_xfp, "%s\n", &MsgBuf[4]);
1951 }
b3cbe40f
EA
1952 else
1953 {
1fd465b3
EA
1954 char mbuf[8];
1955
d916f0ca 1956 Errors++;
1fd465b3
EA
1957 sprintf(mbuf, "%.3s %%s", statmsg);
1958 usrerr(mbuf, &statmsg[4]);
b3cbe40f
EA
1959 }
1960
1961 /*
1962 ** Final cleanup.
1963 ** Log a record of the transaction. Compute the new
1964 ** ExitStat -- if we already had an error, stick with
1965 ** that.
1966 */
1967
68f7099c 1968 if (LogLevel > ((stat == EX_TEMPFAIL) ? 8 : (stat == EX_OK) ? 7 : 6))
3500a891 1969 logdelivery(m, mci, &statmsg[4], ctladdr, xstart, e);
96476cab 1970
ed3d2b02
EA
1971 if (tTd(11, 2))
1972 printf("giveresponse: stat=%d, e->e_message=%s\n",
7ad0fe38 1973 stat, e->e_message == NULL ? "<NULL>" : e->e_message);
ed3d2b02 1974
ed45aae1
EA
1975 if (stat != EX_TEMPFAIL)
1976 setstat(stat);
f2a96b27 1977 if (stat != EX_OK && (stat != EX_TEMPFAIL || e->e_message == NULL))
baa0c390
EA
1978 {
1979 if (e->e_message != NULL)
1980 free(e->e_message);
1981 e->e_message = newstr(&statmsg[4]);
1982 }
e4602f52 1983 errno = 0;
efe7f723 1984#if NAMED_BIND
88d7486c 1985 h_errno = 0;
a0c75a49 1986#endif
b3cbe40f
EA
1987}
1988\f/*
fe033a8f
EA
1989** LOGDELIVERY -- log the delivery in the system log
1990**
eaad1064
EA
1991** Care is taken to avoid logging lines that are too long, because
1992** some versions of syslog have an unfortunate proclivity for core
1993** dumping. This is a hack, to be sure, that is at best empirical.
1994**
fe033a8f 1995** Parameters:
c0ae0b24
EA
1996** m -- the mailer info. Can be NULL for initial queue.
1997** mci -- the mailer connection info -- can be NULL if the
1998** log is occuring when no connection is active.
1999** stat -- the message to print for the status.
5c18c358 2000** ctladdr -- the controlling address for the to list.
3500a891
EA
2001** xstart -- the transaction start time, used for
2002** computing transaction delay.
c0ae0b24 2003** e -- the current envelope.
fe033a8f
EA
2004**
2005** Returns:
2006** none
2007**
2008** Side Effects:
2009** none
2010*/
2011
179d940c 2012void
3500a891 2013logdelivery(m, mci, stat, ctladdr, xstart, e)
c0ae0b24
EA
2014 MAILER *m;
2015 register MCI *mci;
179d940c 2016 const char *stat;
5c18c358 2017 ADDRESS *ctladdr;
3500a891 2018 time_t xstart;
f2e44ded 2019 register ENVELOPE *e;
fe033a8f 2020{
fc93dffb 2021# ifdef LOG
5c18c358 2022 register char *bp;
eaad1064
EA
2023 register char *p;
2024 int l;
ef71c549 2025 char buf[512];
fe033a8f 2026
2bbc90ee 2027# if (SYSLOG_BUFSIZE) >= 256
5c18c358
EA
2028 bp = buf;
2029 if (ctladdr != NULL)
2030 {
2031 strcpy(bp, ", ctladdr=");
ab88ddec 2032 strcat(bp, shortenstring(ctladdr->q_paddr, 83));
5c18c358
EA
2033 bp += strlen(bp);
2034 if (bitset(QGOODUID, ctladdr->q_flags))
2035 {
2036 (void) sprintf(bp, " (%d/%d)",
2037 ctladdr->q_uid, ctladdr->q_gid);
2038 bp += strlen(bp);
2039 }
2040 }
2041
3500a891 2042 sprintf(bp, ", delay=%s", pintvl(curtime() - e->e_ctime, TRUE));
5c18c358 2043 bp += strlen(bp);
c0ae0b24 2044
3500a891
EA
2045 if (xstart != (time_t) 0)
2046 {
2047 sprintf(bp, ", xdelay=%s", pintvl(curtime() - xstart, TRUE));
2048 bp += strlen(bp);
2049 }
2050
4e82a943 2051 if (m != NULL)
9b95d94a 2052 {
5c18c358
EA
2053 (void) strcpy(bp, ", mailer=");
2054 (void) strcat(bp, m->m_name);
2055 bp += strlen(bp);
9b95d94a 2056 }
4e82a943
EA
2057
2058 if (mci != NULL && mci->mci_host != NULL)
9b95d94a 2059 {
9b95d94a 2060# ifdef DAEMON
3341995c 2061 extern SOCKADDR CurHostAddr;
4e82a943
EA
2062# endif
2063
5c18c358
EA
2064 (void) strcpy(bp, ", relay=");
2065 (void) strcat(bp, mci->mci_host);
9b95d94a 2066
4e82a943 2067# ifdef DAEMON
d285c43b 2068 (void) strcat(bp, " [");
5c18c358 2069 (void) strcat(bp, anynet_ntoa(&CurHostAddr));
d285c43b 2070 (void) strcat(bp, "]");
9b95d94a 2071# endif
9b95d94a 2072 }
8fbbb079 2073 else if (strcmp(stat, "queued") != 0)
4e82a943
EA
2074 {
2075 char *p = macvalue('h', e);
fc93dffb 2076
4e82a943
EA
2077 if (p != NULL && p[0] != '\0')
2078 {
5c18c358
EA
2079 (void) strcpy(bp, ", relay=");
2080 (void) strcat(bp, p);
4e82a943
EA
2081 }
2082 }
95203269 2083 bp += strlen(bp);
eaad1064 2084
2bbc90ee
EA
2085#define STATLEN (((SYSLOG_BUFSIZE) - 100) / 4)
2086#if (STATLEN) < 63
2087# undef STATLEN
2088# define STATLEN 63
2089#endif
2090#if (STATLEN) > 203
2091# undef STATLEN
2092# define STATLEN 203
2093#endif
2094
2095 if ((bp - buf) > (sizeof buf - ((STATLEN) + 20)))
eaad1064
EA
2096 {
2097 /* desperation move -- truncate data */
2bbc90ee 2098 bp = buf + sizeof buf - ((STATLEN) + 17);
eaad1064
EA
2099 strcpy(bp, "...");
2100 bp += 3;
2101 }
2102
2103 (void) strcpy(bp, ", stat=");
2104 bp += strlen(bp);
2bbc90ee
EA
2105
2106 (void) strcpy(bp, shortenstring(stat, (STATLEN)));
ef71c549 2107
eaad1064
EA
2108 l = SYSLOG_BUFSIZE - 100 - strlen(buf);
2109 p = e->e_to;
2604d017 2110 while (strlen(p) >= (SIZE_T) l)
eaad1064
EA
2111 {
2112 register char *q = strchr(p + l, ',');
2113
58e480ef 2114 if (q == NULL)
eaad1064
EA
2115 break;
2116 syslog(LOG_INFO, "%s: to=%.*s [more]%s",
2117 e->e_id, ++q - p, p, buf);
2118 p = q;
2119 }
2120 syslog(LOG_INFO, "%s: to=%s%s", e->e_id, p, buf);
2bbc90ee
EA
2121
2122# else /* we have a very short log buffer size */
2123
ec33213e 2124 l = SYSLOG_BUFSIZE - 85;
2bbc90ee
EA
2125 p = e->e_to;
2126 while (strlen(p) >= l)
2127 {
2128 register char *q = strchr(p + l, ',');
2129
2130 if (q == NULL)
2131 break;
2132 syslog(LOG_INFO, "%s: to=%.*s [more]",
2133 e->e_id, ++q - p, p);
2134 p = q;
2135 }
2136 syslog(LOG_INFO, "%s: to=%s", e->e_id, p);
2137
2138 if (ctladdr != NULL)
2139 {
2140 bp = buf;
2141 strcpy(buf, "ctladdr=");
2142 bp += strlen(buf);
2143 strcpy(bp, shortenstring(ctladdr->q_paddr, 83));
2144 bp += strlen(buf);
2145 if (bitset(QGOODUID, ctladdr->q_flags))
2146 {
2147 (void) sprintf(bp, " (%d/%d)",
2148 ctladdr->q_uid, ctladdr->q_gid);
2149 bp += strlen(bp);
2150 }
2151 syslog(LOG_INFO, "%s: %s", e->e_id, buf);
2152 }
3e05a82f
EA
2153 bp = buf;
2154 sprintf(bp, "delay=%s", pintvl(curtime() - e->e_ctime, TRUE));
2155 bp += strlen(bp);
3500a891
EA
2156 if (xstart != (time_t) 0)
2157 {
2158 sprintf(bp, ", xdelay=%s", pintvl(curtime() - xstart, TRUE));
2159 bp += strlen(bp);
2160 }
2bbc90ee
EA
2161
2162 if (m != NULL)
3e05a82f
EA
2163 {
2164 sprintf(bp, ", mailer=%s", m->m_name);
2165 bp += strlen(bp);
2166 }
e5b0f01f 2167 syslog(LOG_INFO, "%s: %s", e->e_id, buf);
2bbc90ee 2168
e5b0f01f 2169 buf[0] = '\0';
2bbc90ee
EA
2170 if (mci != NULL && mci->mci_host != NULL)
2171 {
2172# ifdef DAEMON
2173 extern SOCKADDR CurHostAddr;
2174# endif
2175
2c5b66fc 2176 sprintf(buf, "relay=%s", mci->mci_host);
2bbc90ee
EA
2177
2178# ifdef DAEMON
e5b0f01f
EA
2179 (void) strcat(buf, " [");
2180 (void) strcat(buf, anynet_ntoa(&CurHostAddr));
2181 (void) strcat(buf, "]");
2bbc90ee 2182# endif
2bbc90ee 2183 }
8fbbb079 2184 else if (strcmp(stat, "queued") != 0)
2bbc90ee
EA
2185 {
2186 char *p = macvalue('h', e);
2187
2188 if (p != NULL && p[0] != '\0')
2c5b66fc 2189 sprintf(buf, "relay=%s", p);
2bbc90ee 2190 }
e5b0f01f
EA
2191 if (buf[0] != '\0')
2192 syslog(LOG_INFO, "%s: %s", e->e_id, buf);
2bbc90ee 2193
2bbc90ee
EA
2194 syslog(LOG_INFO, "%s: stat=%s", e->e_id, shortenstring(stat, 63));
2195# endif /* short log buffer */
f3d8f6d6 2196# endif /* LOG */
fe033a8f
EA
2197}
2198\f/*
dd1fe05b 2199** PUTFROMLINE -- output a UNIX-style from line (or whatever)
b3cbe40f 2200**
3c567393
EA
2201** then passes the rest of the message through. If we have
2202** managed to extract a date already, use that; otherwise,
2203** use the current date/time.
b3cbe40f 2204**
a73ae8ac
EA
2205** One of the ugliest hacks seen by human eyes is contained herein:
2206** UUCP wants those stupid "remote from <host>" lines. Why oh why
2207** does a well-meaning programmer such as myself have to deal with
2208** this kind of antique garbage????
dd1fe05b 2209**
b3cbe40f 2210** Parameters:
23fafb99
EA
2211** mci -- the connection information.
2212** e -- the envelope.
b3cbe40f
EA
2213**
2214** Returns:
dd1fe05b 2215** none
b3cbe40f
EA
2216**
2217** Side Effects:
dd1fe05b 2218** outputs some text to fp.
b3cbe40f
EA
2219*/
2220
179d940c 2221void
23fafb99
EA
2222putfromline(mci, e)
2223 register MCI *mci;
f2e44ded 2224 ENVELOPE *e;
b3cbe40f 2225{
2bee003d 2226 char *template = "\201l\n";
dd1fe05b 2227 char buf[MAXLINE];
3c567393 2228 extern char SentDate[];
b3cbe40f 2229
23fafb99 2230 if (bitnset(M_NHDR, mci->mci_mailer->m_flags))
dd1fe05b 2231 return;
74c5fe7c 2232
23fafb99 2233 if (bitnset(M_UGLYUUCP, mci->mci_mailer->m_flags))
79bd7c07 2234 {
9aecbdbe
EA
2235 char *bang;
2236 char xbuf[MAXLINE];
79bd7c07 2237
832e8a27 2238 expand("\201g", buf, sizeof buf, e);
f3d8f6d6 2239 bang = strchr(buf, '!');
dd1fe05b 2240 if (bang == NULL)
1673be04
EA
2241 {
2242 errno = 0;
2243 syserr("554 No ! in UUCP From address! (%s given)", buf);
2244 }
dd1fe05b 2245 else
7338e3d4 2246 {
9aecbdbe 2247 *bang++ = '\0';
2bee003d 2248 (void) sprintf(xbuf, "From %s \201d remote from %s\n", bang, buf);
9aecbdbe 2249 template = xbuf;
7338e3d4 2250 }
79bd7c07 2251 }
832e8a27 2252 expand(template, buf, sizeof buf, e);
7905af2d 2253 putxline(buf, mci, PXLF_NOTHINGSPECIAL);
79bd7c07
EA
2254}
2255\f/*
6acfa498 2256** PUTBODY -- put the body of a message.
cbdb7357
EA
2257**
2258** Parameters:
23fafb99 2259** mci -- the connection information.
6acfa498 2260** e -- the envelope to put out.
2f6a8a78
EA
2261** separator -- if non-NULL, a message separator that must
2262** not be permitted in the resulting message.
cbdb7357
EA
2263**
2264** Returns:
2265** none.
2266**
2267** Side Effects:
6acfa498 2268** The message is written onto fp.
cbdb7357
EA
2269*/
2270
0d721ffb
EA
2271/* values for output state variable */
2272#define OS_HEAD 0 /* at beginning of line */
2273#define OS_CR 1 /* read a carriage return */
2274#define OS_INLINE 2 /* putting rest of line */
2275
179d940c 2276void
51d448e5 2277putbody(mci, e, separator)
23fafb99 2278 register MCI *mci;
6acfa498 2279 register ENVELOPE *e;
2f6a8a78 2280 char *separator;
cbdb7357 2281{
6acfa498 2282 char buf[MAXLINE];
cbdb7357 2283
3c7fe765 2284 /*
6acfa498 2285 ** Output the body of the message
3c7fe765
EA
2286 */
2287
18a81ac0 2288 if (e->e_dfp == NULL && bitset(EF_HAS_DF, e->e_flags))
cd37f61d 2289 {
18a81ac0
EA
2290 char *df = queuename(e, 'd');
2291
2292 e->e_dfp = fopen(df, "r");
cd37f61d
EA
2293 if (e->e_dfp == NULL)
2294 syserr("putbody: Cannot open %s for %s from %s",
18a81ac0 2295 df, e->e_to, e->e_from.q_paddr);
cd37f61d 2296 }
6acfa498 2297 if (e->e_dfp == NULL)
7338e3d4 2298 {
cd37f61d 2299 if (bitset(MCIF_INHEADER, mci->mci_flags))
78bbbc48 2300 {
cd37f61d
EA
2301 putline("", mci);
2302 mci->mci_flags &= ~MCIF_INHEADER;
c23930c0 2303 }
cd37f61d
EA
2304 putline("<<< No Message Collected >>>", mci);
2305 goto endofmessage;
84daea29 2306 }
cd37f61d 2307 if (e->e_dfino == (ino_t) 0)
f009d24b
EA
2308 {
2309 struct stat stbuf;
2310
2311 if (fstat(fileno(e->e_dfp), &stbuf) < 0)
2312 e->e_dfino = -1;
2313 else
bb4fde22
EA
2314 {
2315 e->e_dfdev = stbuf.st_dev;
f009d24b 2316 e->e_dfino = stbuf.st_ino;
bb4fde22 2317 }
f009d24b 2318 }
0d721ffb 2319 rewind(e->e_dfp);
c23930c0 2320
8bc4f1c6 2321#if MIME8TO7
0d721ffb
EA
2322 if (bitset(MCIF_CVT8TO7, mci->mci_flags))
2323 {
022362dd
EA
2324 char *boundaries[MAXMIMENESTING + 1];
2325
bb4fde22
EA
2326 /*
2327 ** Do 8 to 7 bit MIME conversion.
2328 */
2329
2330 /* make sure it looks like a MIME message */
0d721ffb
EA
2331 if (hvalue("MIME-Version", e->e_header) == NULL)
2332 putline("MIME-Version: 1.0", mci);
bb4fde22 2333
bb4fde22 2334 if (hvalue("Content-Type", e->e_header) == NULL)
a50ac3e2 2335 {
a50ac3e2 2336 sprintf(buf, "Content-Type: text/plain; charset=%s",
3caf3b1f 2337 defcharset(e));
a50ac3e2
EA
2338 putline(buf, mci);
2339 }
bb4fde22
EA
2340
2341 /* now do the hard work */
022362dd
EA
2342 boundaries[0] = NULL;
2343 mime8to7(mci, e->e_header, e, boundaries, M87F_OUTER);
0d721ffb
EA
2344 }
2345 else
8bc4f1c6 2346#endif
0d721ffb
EA
2347 {
2348 int ostate;
2349 register char *bp;
2350 register char *pbp;
2351 register int c;
2352 int padc;
2353 char *buflim;
ea07b2d2 2354 int pos = 0;
0d721ffb
EA
2355 char peekbuf[10];
2356
2357 /* we can pass it through unmodified */
2358 if (bitset(MCIF_INHEADER, mci->mci_flags))
c23930c0 2359 {
0d721ffb
EA
2360 putline("", mci);
2361 mci->mci_flags &= ~MCIF_INHEADER;
c23930c0 2362 }
0d721ffb
EA
2363
2364 /* determine end of buffer; allow for short mailer lines */
2365 buflim = &buf[sizeof buf - 1];
098e8e2c
EA
2366 if (mci->mci_mailer->m_linelimit > 0 &&
2367 mci->mci_mailer->m_linelimit < sizeof buf - 1)
0d721ffb
EA
2368 buflim = &buf[mci->mci_mailer->m_linelimit - 1];
2369
2370 /* copy temp file to output with mapping */
2371 ostate = OS_HEAD;
2372 bp = buf;
2373 pbp = peekbuf;
2374 while (!ferror(mci->mci_out))
84daea29 2375 {
0d721ffb
EA
2376 register char *xp;
2377
2378 if (pbp > peekbuf)
2379 c = *--pbp;
52d719ca 2380 else if ((c = getc(e->e_dfp)) == EOF)
0d721ffb
EA
2381 break;
2382 if (bitset(MCIF_7BIT, mci->mci_flags))
2383 c &= 0x7f;
2384 switch (ostate)
2f6a8a78 2385 {
0d721ffb
EA
2386 case OS_HEAD:
2387 if (c != '\r' && c != '\n' && bp < buflim)
2388 {
2389 *bp++ = c;
2390 break;
2391 }
2392
2393 /* check beginning of line for special cases */
2394 *bp = '\0';
2395 pos = 0;
2396 padc = EOF;
c23930c0
EA
2397 if (buf[0] == 'F' &&
2398 bitnset(M_ESCFROM, mci->mci_mailer->m_flags) &&
2399 strncmp(buf, "From ", 5) == 0)
0d721ffb
EA
2400 {
2401 padc = '>';
2402 }
c23930c0
EA
2403 if (buf[0] == '-' && buf[1] == '-' &&
2404 separator != NULL)
2405 {
2406 /* possible separator */
2407 int sl = strlen(separator);
2f6a8a78 2408
c23930c0 2409 if (strncmp(&buf[2], separator, sl) == 0)
0d721ffb 2410 padc = ' ';
c23930c0 2411 }
0d721ffb
EA
2412 if (buf[0] == '.' &&
2413 bitnset(M_XDOT, mci->mci_mailer->m_flags))
2414 {
2415 padc = '.';
2416 }
2417
2418 /* now copy out saved line */
2419 if (TrafficLogFile != NULL)
2420 {
2421 fprintf(TrafficLogFile, "%05d >>> ", getpid());
2422 if (padc != EOF)
52d719ca 2423 putc(padc, TrafficLogFile);
0d721ffb 2424 for (xp = buf; xp < bp; xp++)
52d719ca 2425 putc(*xp, TrafficLogFile);
0d721ffb
EA
2426 if (c == '\n')
2427 fputs(mci->mci_mailer->m_eol,
2428 TrafficLogFile);
2429 }
2430 if (padc != EOF)
2431 {
52d719ca 2432 putc(padc, mci->mci_out);
0d721ffb
EA
2433 pos++;
2434 }
2435 for (xp = buf; xp < bp; xp++)
52d719ca 2436 putc(*xp, mci->mci_out);
0d721ffb
EA
2437 if (c == '\n')
2438 {
2439 fputs(mci->mci_mailer->m_eol,
2440 mci->mci_out);
2441 pos = 0;
2442 }
2443 else
2444 {
2445 pos += bp - buf;
a4041586
EA
2446 if (c != '\r')
2447 *pbp++ = c;
0d721ffb
EA
2448 }
2449 bp = buf;
2450
2451 /* determine next state */
2452 if (c == '\n')
2453 ostate = OS_HEAD;
2454 else if (c == '\r')
2455 ostate = OS_CR;
2456 else
2457 ostate = OS_INLINE;
2458 continue;
2459
2460 case OS_CR:
2461 if (c == '\n')
2462 {
2463 /* got CRLF */
2464 fputs(mci->mci_mailer->m_eol, mci->mci_out);
2465 if (TrafficLogFile != NULL)
2466 {
2467 fputs(mci->mci_mailer->m_eol,
2468 TrafficLogFile);
2469 }
2470 ostate = OS_HEAD;
2471 continue;
2472 }
2473
2474 /* had a naked carriage return */
2475 *pbp++ = c;
2476 c = '\r';
68e6bb99 2477 goto putch;
0d721ffb
EA
2478
2479 case OS_INLINE:
2480 if (c == '\r')
2481 {
2482 ostate = OS_CR;
2483 continue;
2484 }
68e6bb99 2485putch:
098e8e2c
EA
2486 if (mci->mci_mailer->m_linelimit > 0 &&
2487 pos > mci->mci_mailer->m_linelimit &&
0d721ffb
EA
2488 c != '\n')
2489 {
2490 putc('!', mci->mci_out);
2491 fputs(mci->mci_mailer->m_eol, mci->mci_out);
2492 if (TrafficLogFile != NULL)
2493 {
2494 fprintf(TrafficLogFile, "!%s",
2495 mci->mci_mailer->m_eol);
2496 }
2497 ostate = OS_HEAD;
2498 *pbp++ = c;
2499 continue;
2500 }
2501 if (TrafficLogFile != NULL)
52d719ca 2502 putc(c, TrafficLogFile);
0d721ffb
EA
2503 putc(c, mci->mci_out);
2504 pos++;
a4041586 2505 ostate = c == '\n' ? OS_HEAD : OS_INLINE;
0d721ffb 2506 break;
2f6a8a78 2507 }
84daea29 2508 }
0d721ffb 2509 }
84daea29 2510
0d721ffb
EA
2511 if (ferror(e->e_dfp))
2512 {
18a81ac0 2513 syserr("putbody: df%s: read error", e->e_id);
0d721ffb 2514 ExitStat = EX_IOERR;
baa2b877 2515 }
75f95954 2516
0d721ffb 2517endofmessage:
1537ac22 2518 /* some mailers want extra blank line at end of message */
23fafb99
EA
2519 if (bitnset(M_BLANKEND, mci->mci_mailer->m_flags) &&
2520 buf[0] != '\0' && buf[0] != '\n')
2521 putline("", mci);
1537ac22 2522
23fafb99
EA
2523 (void) fflush(mci->mci_out);
2524 if (ferror(mci->mci_out) && errno != EPIPE)
84daea29 2525 {
6acfa498
EA
2526 syserr("putbody: write error");
2527 ExitStat = EX_IOERR;
84daea29 2528 }
6acfa498 2529 errno = 0;
bc854e30 2530}
6acfa498
EA
2531\f/*
2532** MAILFILE -- Send a message to a file.
2533**
2534** If the file has the setuid/setgid bits set, but NO execute
2535** bits, sendmail will try to become the owner of that file
2536** rather than the real user. Obviously, this only works if
2537** sendmail runs as root.
2538**
2539** This could be done as a subordinate mailer, except that it
2540** is used implicitly to save messages in ~/dead.letter. We
2541** view this as being sufficiently important as to include it
2542** here. For example, if the system is dying, we shouldn't have
2543** to create another process plus some pipes to save the message.
2544**
2545** Parameters:
2546** filename -- the name of the file to send to.
2547** ctladdr -- the controlling address header -- includes
2548** the userid/groupid to be when sending.
b6f25ddb
EA
2549** sfflags -- flags for opening.
2550** e -- the current envelope.
6acfa498
EA
2551**
2552** Returns:
2553** The exit code associated with the operation.
2554**
2555** Side Effects:
2556** none.
2557*/
bc854e30 2558
179d940c 2559int
b6f25ddb 2560mailfile(filename, ctladdr, sfflags, e)
6acfa498
EA
2561 char *filename;
2562 ADDRESS *ctladdr;
b6f25ddb 2563 int sfflags;
bc854e30 2564 register ENVELOPE *e;
bc854e30 2565{
6acfa498 2566 register FILE *f;
ea07b2d2 2567 register int pid = -1;
6acfa498 2568 int mode;
84daea29 2569
831d7357
EA
2570 if (tTd(11, 1))
2571 {
2572 printf("mailfile %s\n ctladdr=", filename);
2573 printaddr(ctladdr, FALSE);
2574 }
2575
8e5c6745
EA
2576 if (e->e_xfp != NULL)
2577 fflush(e->e_xfp);
2578
6acfa498
EA
2579 /*
2580 ** Fork so we can change permissions here.
2581 ** Note that we MUST use fork, not vfork, because of
2582 ** the complications of calling subroutines, etc.
2583 */
2584
2585 DOFORK(fork);
2586
2587 if (pid < 0)
2588 return (EX_OSERR);
2589 else if (pid == 0)
75f95954 2590 {
6acfa498
EA
2591 /* child -- actually write to file */
2592 struct stat stb;
2c2b6557 2593 struct stat fsb;
23fafb99 2594 MCI mcibuf;
99fd9645 2595 int oflags = O_WRONLY|O_APPEND;
8726396d 2596 int oflags = O_WRONLY|O_APPEND;
75f95954 2597
2c2b6557 2598 if (e->e_lockfp != NULL)
da8ca152 2599 (void) close(fileno(e->e_lockfp));
2c2b6557 2600
39270cfd
EA
2601 (void) setsignal(SIGINT, SIG_DFL);
2602 (void) setsignal(SIGHUP, SIG_DFL);
2603 (void) setsignal(SIGTERM, SIG_DFL);
6acfa498 2604 (void) umask(OldUmask);
b6f25ddb
EA
2605 e->e_to = filename;
2606 ExitStat = EX_OK;
75f95954 2607
99fd9645
EA
2608#ifdef HASLSTAT
2609 if ((SafeFileEnv != NULL ? lstat(filename, &stb)
2610 : stat(filename, &stb)) < 0)
2611#else
6acfa498 2612 if (stat(filename, &stb) < 0)
8726396d 2613 {
99fd9645
EA
2614#endif
2615 {
6f7f4e2c 2616 stb.st_mode = FileMode;
99fd9645
EA
2617 oflags |= O_CREAT|O_EXCL;
2618 }
2619 else if (bitset(0111, stb.st_mode) || stb.st_nlink != 1 ||
2620 (SafeFileEnv != NULL && !S_ISREG(stb.st_mode)))
2c2b6557 2621 exit(EX_CANTCREAT);
6acfa498 2622 mode = stb.st_mode;
07800f98 2623
6acfa498
EA
2624 /* limit the errors to those actually caused in the child */
2625 errno = 0;
2626 ExitStat = EX_OK;
07800f98 2627
b6f25ddb 2628 if (ctladdr != NULL || bitset(SFF_RUNASREALUID, sfflags))
07800f98 2629 {
6acfa498
EA
2630 /* ignore setuid and setgid bits */
2631 mode &= ~(S_ISGID|S_ISUID);
07800f98 2632 }
07800f98 2633
6acfa498 2634 /* we have to open the dfile BEFORE setuid */
18a81ac0 2635 if (e->e_dfp == NULL && bitset(EF_HAS_DF, e->e_flags))
813d8709 2636 {
18a81ac0
EA
2637 char *df = queuename(e, 'd');
2638
2639 e->e_dfp = fopen(df, "r");
6acfa498 2640 if (e->e_dfp == NULL)
78bbbc48 2641 {
6acfa498 2642 syserr("mailfile: Cannot open %s for %s from %s",
18a81ac0 2643 df, e->e_to, e->e_from.q_paddr);
78bbbc48 2644 }
6acfa498 2645 }
78bbbc48 2646
e0c8c651 2647 if (SafeFileEnv != NULL && SafeFileEnv[0] != '\0')
99fd9645
EA
2648 {
2649 int i;
2650
2651 if (chroot(SafeFileEnv) < 0)
2652 {
2653 syserr("mailfile: Cannot chroot(%s)",
2654 SafeFileEnv);
2655 exit(EX_CANTCREAT);
2656 }
2657 i = strlen(SafeFileEnv);
2658 if (strncmp(SafeFileEnv, filename, i) == 0)
2659 filename += i;
2660 }
2661 if (chdir("/") < 0)
2662 syserr("mailfile: cannot chdir(/)");
2663
b6f25ddb
EA
2664 /* select a new user to run as */
2665 if (!bitset(SFF_RUNASREALUID, sfflags))
6acfa498 2666 {
b6f25ddb
EA
2667 if (bitset(S_ISUID, mode))
2668 {
2669 RealUserName = NULL;
2670 RealUid = stb.st_uid;
2671 }
2672 else if (ctladdr != NULL && ctladdr->q_uid != 0)
2673 {
2674 if (ctladdr->q_ruser != NULL)
2675 RealUserName = ctladdr->q_ruser;
2676 else
2677 RealUserName = ctladdr->q_user;
2678 RealUid = ctladdr->q_uid;
2679 }
2680 else if (FileMailer != NULL && FileMailer->m_uid != 0)
2681 {
2682 RealUserName = DefUser;
2683 RealUid = FileMailer->m_uid;
2684 }
2685 else
2686 {
2687 RealUserName = DefUser;
2688 RealUid = DefUid;
2689 }
2690
2691 /* select a new group to run as */
2692 if (bitset(S_ISGID, mode))
2693 RealGid = stb.st_gid;
2694 else if (ctladdr != NULL && ctladdr->q_uid != 0)
2695 RealGid = ctladdr->q_gid;
0c35b842 2696 else if (FileMailer != NULL && FileMailer->m_gid != 0)
b6f25ddb 2697 RealGid = FileMailer->m_gid;
0c35b842 2698 else
b6f25ddb 2699 RealGid = DefGid;
813d8709 2700 }
b6f25ddb
EA
2701
2702 /* last ditch */
2703 if (!bitset(SFF_ROOTOK, sfflags))
4ae3ff58 2704 {
b6f25ddb
EA
2705 if (RealUid == 0)
2706 RealUid = DefUid;
2707 if (RealGid == 0)
2708 RealGid = DefGid;
4ae3ff58 2709 }
b6f25ddb
EA
2710
2711 /* now set the group and user ids */
2712 if (RealUserName != NULL)
2713 (void) initgroups(RealUserName, RealGid);
2714 else
2715 (void) setgid(RealGid);
2716 (void) setuid(RealUid);
2717
2718 sfflags |= SFF_NOPATHCHECK;
2719 sfflags &= ~SFF_OPENASROOT;
2720 f = safefopen(filename, oflags, FileMode, sfflags);
6acfa498 2721 if (f == NULL)
cbdb7357 2722 {
6814f197 2723 message("554 cannot open: %s", errstring(errno));
6acfa498 2724 exit(EX_CANTCREAT);
cbdb7357 2725 }
8dcff118 2726
23fafb99
EA
2727 bzero(&mcibuf, sizeof mcibuf);
2728 mcibuf.mci_mailer = FileMailer;
2729 mcibuf.mci_out = f;
2730 if (bitnset(M_7BITS, FileMailer->m_flags))
2731 mcibuf.mci_flags |= MCIF_7BIT;
2732
2733 putfromline(&mcibuf, e);
51d448e5
EA
2734 (*e->e_puthdr)(&mcibuf, e->e_header, e);
2735 (*e->e_putbody)(&mcibuf, e, NULL);
23fafb99 2736 putline("\n", &mcibuf);
6acfa498
EA
2737 if (ferror(f))
2738 {
6814f197 2739 message("451 I/O error: %s", errstring(errno));
6acfa498 2740 setstat(EX_IOERR);
8dcff118 2741 }
6acfa498
EA
2742 (void) xfclose(f, "mailfile", filename);
2743 (void) fflush(stdout);
3c7fe765 2744
6acfa498
EA
2745 /* reset ISUID & ISGID bits for paranoid systems */
2746 (void) chmod(filename, (int) stb.st_mode);
2747 exit(ExitStat);
2748 /*NOTREACHED*/
bc854e30 2749 }
6acfa498 2750 else
3c7fe765 2751 {
6acfa498
EA
2752 /* parent -- wait for exit status */
2753 int st;
bc854e30 2754
6acfa498 2755 st = waitfor(pid);
e3791bb6
EA
2756 if (WIFEXITED(st))
2757 return (WEXITSTATUS(st));
6acfa498 2758 else
6814f197
EA
2759 {
2760 syserr("child died on signal %d", st);
e3791bb6 2761 return (EX_UNAVAILABLE);
6814f197 2762 }
6acfa498 2763 /*NOTREACHED*/
3c7fe765
EA
2764 }
2765}
7e70d3c8
EA
2766\f/*
2767** HOSTSIGNATURE -- return the "signature" for a host.
2768**
2769** The signature describes how we are going to send this -- it
2770** can be just the hostname (for non-Internet hosts) or can be
2771** an ordered list of MX hosts.
2772**
2773** Parameters:
2774** m -- the mailer describing this host.
2775** host -- the host name.
2776** e -- the current envelope.
2777**
2778** Returns:
2779** The signature for this host.
2780**
2781** Side Effects:
2782** Can tweak the symbol table.
2783*/
2784
2785char *
2786hostsignature(m, host, e)
2787 register MAILER *m;
2788 char *host;
2789 ENVELOPE *e;
2790{
2791 register char *p;
2792 register STAB *s;
2793 int i;
2794 int len;
efe7f723 2795#if NAMED_BIND
7e70d3c8
EA
2796 int nmx;
2797 auto int rcode;
db113c28
EA
2798 char *hp;
2799 char *endp;
ea07b2d2 2800 int oldoptions = _res.options;
7e70d3c8 2801 char *mxhosts[MAXMXHOSTS + 1];
7e70d3c8
EA
2802#endif
2803
2804 /*
2805 ** Check to see if this uses IPC -- if not, it can't have MX records.
2806 */
2807
2808 p = m->m_mailer;
2809 if (strcmp(p, "[IPC]") != 0 && strcmp(p, "[TCP]") != 0)
2810 {
2811 /* just an ordinary mailer */
2812 return host;
2813 }
2814
7e70d3c8
EA
2815 /*
2816 ** Look it up in the symbol table.
2817 */
2818
2819 s = stab(host, ST_HOSTSIG, ST_ENTER);
2820 if (s->s_hostsig != NULL)
2821 return s->s_hostsig;
2822
2823 /*
2824 ** Not already there -- create a signature.
2825 */
2826
efe7f723 2827#if NAMED_BIND
c8f4bc0b 2828 if (ConfigLevel < 2)
c8f4bc0b 2829 _res.options &= ~(RES_DEFNAMES | RES_DNSRCH); /* XXX */
c8f4bc0b 2830
db113c28 2831 for (hp = host; hp != NULL; hp = endp)
7e70d3c8 2832 {
db113c28
EA
2833 endp = strchr(hp, ':');
2834 if (endp != NULL)
2835 *endp = '\0';
7e70d3c8 2836
c3577cd6 2837 nmx = getmxrr(hp, mxhosts, TRUE, &rcode);
7e70d3c8 2838
db113c28
EA
2839 if (nmx <= 0)
2840 {
2841 register MCI *mci;
7e70d3c8 2842
db113c28
EA
2843 /* update the connection info for this host */
2844 mci = mci_get(hp, m);
2845 mci->mci_exitstat = rcode;
2846 mci->mci_errno = errno;
8e5c6745 2847 mci->mci_herrno = h_errno;
db113c28
EA
2848
2849 /* and return the original host name as the signature */
2850 nmx = 1;
2851 mxhosts[0] = hp;
2852 }
2853
2854 len = 0;
2855 for (i = 0; i < nmx; i++)
2856 {
2857 len += strlen(mxhosts[i]) + 1;
2858 }
2859 if (s->s_hostsig != NULL)
2860 len += strlen(s->s_hostsig) + 1;
2861 p = xalloc(len);
2862 if (s->s_hostsig != NULL)
2863 {
2864 (void) strcpy(p, s->s_hostsig);
2865 free(s->s_hostsig);
2866 s->s_hostsig = p;
2867 p += strlen(p);
7e70d3c8 2868 *p++ = ':';
db113c28
EA
2869 }
2870 else
2871 s->s_hostsig = p;
2872 for (i = 0; i < nmx; i++)
2873 {
2874 if (i != 0)
2875 *p++ = ':';
2876 strcpy(p, mxhosts[i]);
2877 p += strlen(p);
2878 }
2879 if (endp != NULL)
2880 *endp++ = ':';
7e70d3c8
EA
2881 }
2882 makelower(s->s_hostsig);
c8f4bc0b
EA
2883 if (ConfigLevel < 2)
2884 _res.options = oldoptions;
7e70d3c8
EA
2885#else
2886 /* not using BIND -- the signature is just the host name */
2887 s->s_hostsig = host;
2888#endif
2889 if (tTd(17, 1))
2890 printf("hostsignature(%s) = %s\n", host, s->s_hostsig);
2891 return s->s_hostsig;
2892}