|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Eric P. Allman
3: * Copyright (c) 1988 Regents of the University of California.
4: * All rights reserved.
5: *
6: * Redistribution and use in source and binary forms are permitted
7: * provided that the above copyright notice and this paragraph are
8: * duplicated in all such forms and that any documentation,
9: * advertising materials, and other materials related to such
10: * distribution and use acknowledge that the software was developed
11: * by the University of California, Berkeley. The name of the
12: * University may not be used to endorse or promote products derived
13: * from this software without specific prior written permission.
14: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17: */
18:
19: #ifndef lint
20: static char sccsid[] = "@(#)deliver.c 5.22 (Berkeley) 6/30/88";
21: #endif /* not lint */
22:
23: #include <sendmail.h>
24: #include <sys/signal.h>
25: #include <sys/stat.h>
26: #include <sys/ioctl.h>
27: #include <netdb.h>
28: #include <errno.h>
29: #include <arpa/nameser.h>
30: #include <resolv.h>
31:
32: /*
33: ** DELIVER -- Deliver a message to a list of addresses.
34: **
35: ** This routine delivers to everyone on the same host as the
36: ** user on the head of the list. It is clever about mailers
37: ** that don't handle multiple users. It is NOT guaranteed
38: ** that it will deliver to all these addresses however -- so
39: ** deliver should be called once for each address on the
40: ** list.
41: **
42: ** Parameters:
43: ** e -- the envelope to deliver.
44: ** firstto -- head of the address list to deliver to.
45: **
46: ** Returns:
47: ** zero -- successfully delivered.
48: ** else -- some failure, see ExitStat for more info.
49: **
50: ** Side Effects:
51: ** The standard input is passed off to someone.
52: */
53:
54: deliver(e, firstto)
55: register ENVELOPE *e;
56: ADDRESS *firstto;
57: {
58: char *host; /* host being sent to */
59: char *user; /* user being sent to */
60: char **pvp;
61: register char **mvp;
62: register char *p;
63: register MAILER *m; /* mailer for this recipient */
64: ADDRESS *ctladdr;
65: register ADDRESS *to = firstto;
66: bool clever = FALSE; /* running user smtp to this mailer */
67: ADDRESS *tochain = NULL; /* chain of users in this mailer call */
68: int rcode; /* response code */
69: char *pv[MAXPV+1];
70: char tobuf[MAXLINE-50]; /* text line of to people */
71: char buf[MAXNAME];
72: char tfrombuf[MAXNAME]; /* translated from person */
73: extern bool checkcompat();
74: extern ADDRESS *getctladdr();
75: extern char *remotename();
76:
77: errno = 0;
78: if (bitset(QDONTSEND, to->q_flags))
79: return (0);
80:
81: /* unless interactive, try twice, over a minute */
82: if (OpMode == MD_DAEMON || OpMode == MD_SMTP) {
83: _res.retrans = 30;
84: _res.retry = 2;
85: }
86:
87: m = to->q_mailer;
88: host = to->q_host;
89:
90: # ifdef DEBUG
91: if (tTd(10, 1))
92: printf("\n--deliver, mailer=%d, host=`%s', first user=`%s'\n",
93: m->m_mno, host, to->q_user);
94: # endif DEBUG
95:
96: /*
97: ** If this mailer is expensive, and if we don't want to make
98: ** connections now, just mark these addresses and return.
99: ** This is useful if we want to batch connections to
100: ** reduce load. This will cause the messages to be
101: ** queued up, and a daemon will come along to send the
102: ** messages later.
103: ** This should be on a per-mailer basis.
104: */
105:
106: if (NoConnect && !QueueRun && bitnset(M_EXPENSIVE, m->m_flags) &&
107: !Verbose)
108: {
109: for (; to != NULL; to = to->q_next)
110: {
111: if (bitset(QDONTSEND, to->q_flags) || to->q_mailer != m)
112: continue;
113: to->q_flags |= QQUEUEUP|QDONTSEND;
114: e->e_to = to->q_paddr;
115: message(Arpa_Info, "queued");
116: if (LogLevel > 4)
117: logdelivery("queued");
118: }
119: e->e_to = NULL;
120: return (0);
121: }
122:
123: /*
124: ** Do initial argv setup.
125: ** Insert the mailer name. Notice that $x expansion is
126: ** NOT done on the mailer name. Then, if the mailer has
127: ** a picky -f flag, we insert it as appropriate. This
128: ** code does not check for 'pv' overflow; this places a
129: ** manifest lower limit of 4 for MAXPV.
130: ** The from address rewrite is expected to make
131: ** the address relative to the other end.
132: */
133:
134: /* rewrite from address, using rewriting rules */
135: expand("\001f", buf, &buf[sizeof buf - 1], e);
136: (void) strcpy(tfrombuf, remotename(buf, m, TRUE, TRUE));
137:
138: define('g', tfrombuf, e); /* translated sender address */
139: define('h', host, e); /* to host */
140: Errors = 0;
141: pvp = pv;
142: *pvp++ = m->m_argv[0];
143:
144: /* insert -f or -r flag as appropriate */
145: if (FromFlag && (bitnset(M_FOPT, m->m_flags) || bitnset(M_ROPT, m->m_flags)))
146: {
147: if (bitnset(M_FOPT, m->m_flags))
148: *pvp++ = "-f";
149: else
150: *pvp++ = "-r";
151: expand("\001g", buf, &buf[sizeof buf - 1], e);
152: *pvp++ = newstr(buf);
153: }
154:
155: /*
156: ** Append the other fixed parts of the argv. These run
157: ** up to the first entry containing "$u". There can only
158: ** be one of these, and there are only a few more slots
159: ** in the pv after it.
160: */
161:
162: for (mvp = m->m_argv; (p = *++mvp) != NULL; )
163: {
164: while ((p = index(p, '\001')) != NULL)
165: if (*++p == 'u')
166: break;
167: if (p != NULL)
168: break;
169:
170: /* this entry is safe -- go ahead and process it */
171: expand(*mvp, buf, &buf[sizeof buf - 1], e);
172: *pvp++ = newstr(buf);
173: if (pvp >= &pv[MAXPV - 3])
174: {
175: syserr("Too many parameters to %s before $u", pv[0]);
176: return (-1);
177: }
178: }
179:
180: /*
181: ** If we have no substitution for the user name in the argument
182: ** list, we know that we must supply the names otherwise -- and
183: ** SMTP is the answer!!
184: */
185:
186: if (*mvp == NULL)
187: {
188: /* running SMTP */
189: # ifdef SMTP
190: clever = TRUE;
191: *pvp = NULL;
192: # else SMTP
193: /* oops! we don't implement SMTP */
194: syserr("SMTP style mailer");
195: return (EX_SOFTWARE);
196: # endif SMTP
197: }
198:
199: /*
200: ** At this point *mvp points to the argument with $u. We
201: ** run through our address list and append all the addresses
202: ** we can. If we run out of space, do not fret! We can
203: ** always send another copy later.
204: */
205:
206: tobuf[0] = '\0';
207: e->e_to = tobuf;
208: ctladdr = NULL;
209: for (; to != NULL; to = to->q_next)
210: {
211: /* avoid sending multiple recipients to dumb mailers */
212: if (tobuf[0] != '\0' && !bitnset(M_MUSER, m->m_flags))
213: break;
214:
215: /* if already sent or not for this host, don't send */
216: if (bitset(QDONTSEND, to->q_flags) ||
217: strcmp(to->q_host, host) != 0 ||
218: to->q_mailer != firstto->q_mailer)
219: continue;
220:
221: /* avoid overflowing tobuf */
222: if (sizeof tobuf - (strlen(to->q_paddr) + strlen(tobuf) + 2) < 0)
223: break;
224:
225: # ifdef DEBUG
226: if (tTd(10, 1))
227: {
228: printf("\nsend to ");
229: printaddr(to, FALSE);
230: }
231: # endif DEBUG
232:
233: /* compute effective uid/gid when sending */
234: if (to->q_mailer == ProgMailer)
235: ctladdr = getctladdr(to);
236:
237: user = to->q_user;
238: e->e_to = to->q_paddr;
239: to->q_flags |= QDONTSEND;
240:
241: /*
242: ** Check to see that these people are allowed to
243: ** talk to each other.
244: */
245:
246: if (m->m_maxsize != 0 && e->e_msgsize > m->m_maxsize)
247: {
248: NoReturn = TRUE;
249: usrerr("Message is too large; %ld bytes max", m->m_maxsize);
250: giveresponse(EX_UNAVAILABLE, m, e);
251: continue;
252: }
253: if (!checkcompat(to))
254: {
255: giveresponse(EX_UNAVAILABLE, m, e);
256: continue;
257: }
258:
259: /*
260: ** Strip quote bits from names if the mailer is dumb
261: ** about them.
262: */
263:
264: if (bitnset(M_STRIPQ, m->m_flags))
265: {
266: stripquotes(user, TRUE);
267: stripquotes(host, TRUE);
268: }
269: else
270: {
271: stripquotes(user, FALSE);
272: stripquotes(host, FALSE);
273: }
274:
275: /* hack attack -- delivermail compatibility */
276: if (m == ProgMailer && *user == '|')
277: user++;
278:
279: /*
280: ** If an error message has already been given, don't
281: ** bother to send to this address.
282: **
283: ** >>>>>>>>>> This clause assumes that the local mailer
284: ** >> NOTE >> cannot do any further aliasing; that
285: ** >>>>>>>>>> function is subsumed by sendmail.
286: */
287:
288: if (bitset(QBADADDR|QQUEUEUP, to->q_flags))
289: continue;
290:
291: /* save statistics.... */
292: markstats(e, to);
293:
294: /*
295: ** See if this user name is "special".
296: ** If the user name has a slash in it, assume that this
297: ** is a file -- send it off without further ado. Note
298: ** that this type of addresses is not processed along
299: ** with the others, so we fudge on the To person.
300: */
301:
302: if (m == LocalMailer)
303: {
304: if (user[0] == '/')
305: {
306: rcode = mailfile(user, getctladdr(to));
307: giveresponse(rcode, m, e);
308: continue;
309: }
310: }
311:
312: /*
313: ** Address is verified -- add this user to mailer
314: ** argv, and add it to the print list of recipients.
315: */
316:
317: /* link together the chain of recipients */
318: to->q_tchain = tochain;
319: tochain = to;
320:
321: /* create list of users for error messages */
322: (void) strcat(tobuf, ",");
323: (void) strcat(tobuf, to->q_paddr);
324: define('u', user, e); /* to user */
325: define('z', to->q_home, e); /* user's home */
326:
327: /*
328: ** Expand out this user into argument list.
329: */
330:
331: if (!clever)
332: {
333: expand(*mvp, buf, &buf[sizeof buf - 1], e);
334: *pvp++ = newstr(buf);
335: if (pvp >= &pv[MAXPV - 2])
336: {
337: /* allow some space for trailing parms */
338: break;
339: }
340: }
341: }
342:
343: /* see if any addresses still exist */
344: if (tobuf[0] == '\0')
345: {
346: define('g', (char *) NULL, e);
347: return (0);
348: }
349:
350: /* print out messages as full list */
351: e->e_to = tobuf + 1;
352:
353: /*
354: ** Fill out any parameters after the $u parameter.
355: */
356:
357: while (!clever && *++mvp != NULL)
358: {
359: expand(*mvp, buf, &buf[sizeof buf - 1], e);
360: *pvp++ = newstr(buf);
361: if (pvp >= &pv[MAXPV])
362: syserr("deliver: pv overflow after $u for %s", pv[0]);
363: }
364: *pvp++ = NULL;
365:
366: /*
367: ** Call the mailer.
368: ** The argument vector gets built, pipes
369: ** are created as necessary, and we fork & exec as
370: ** appropriate.
371: ** If we are running SMTP, we just need to clean up.
372: */
373:
374: if (ctladdr == NULL)
375: ctladdr = &e->e_from;
376: _res.options &= ~(RES_DEFNAMES | RES_DNSRCH); /* XXX */
377: #ifdef SMTP
378: if (clever) {
379: expand("\001w", buf, &buf[sizeof(buf) - 1], e);
380: rcode = EX_OK;
381: if (host[0] == '[') {
382: Nmx = 1;
383: MxHosts[0] = host;
384: } else
385: Nmx = getmxrr(host, MxHosts, buf, &rcode);
386: if (Nmx >= 0) {
387: message(Arpa_Info, "Connecting to %s (%s)...",
388: MxHosts[0], m->m_name);
389: if ((rcode = smtpinit(m, pv)) == EX_OK) {
390: /* send the recipient list */
391: tobuf[0] = '\0';
392: for (to = tochain; to; to = to->q_tchain) {
393: register int i;
394: register char *t = tobuf;
395:
396: e->e_to = to->q_paddr;
397: if ((i = smtprcpt(to, m)) != EX_OK) {
398: markfailure(e, to, i);
399: giveresponse(i, m, e);
400: }
401: else {
402: *t++ = ',';
403: for (p = to->q_paddr; *p; *t++ = *p++);
404: }
405: }
406:
407: /* now send the data */
408: if (tobuf[0] == '\0')
409: e->e_to = NULL;
410: else {
411: e->e_to = tobuf + 1;
412: rcode = smtpdata(m, e);
413: }
414:
415: /* now close the connection */
416: smtpquit(m);
417: }
418: }
419: }
420: else
421: #endif /* SMTP */
422: {
423: message(Arpa_Info, "Connecting to %s (%s)...", host, m->m_name);
424: rcode = sendoff(e, m, pv, ctladdr);
425: }
426: _res.options |= RES_DEFNAMES | RES_DNSRCH; /* XXX */
427:
428: /*
429: ** Do final status disposal.
430: ** We check for something in tobuf for the SMTP case.
431: ** If we got a temporary failure, arrange to queue the
432: ** addressees.
433: */
434:
435: if (tobuf[0] != '\0')
436: giveresponse(rcode, m, e);
437: if (rcode != EX_OK)
438: for (to = tochain; to != NULL; to = to->q_tchain)
439: markfailure(e, to, rcode);
440:
441: errno = 0;
442: define('g', (char *) NULL, e);
443: return (rcode);
444: }
445: /*
446: ** MARKFAILURE -- mark a failure on a specific address.
447: **
448: ** Parameters:
449: ** e -- the envelope we are sending.
450: ** q -- the address to mark.
451: ** rcode -- the code signifying the particular failure.
452: **
453: ** Returns:
454: ** none.
455: **
456: ** Side Effects:
457: ** marks the address (and possibly the envelope) with the
458: ** failure so that an error will be returned or
459: ** the message will be queued, as appropriate.
460: */
461:
462: markfailure(e, q, rcode)
463: register ENVELOPE *e;
464: register ADDRESS *q;
465: int rcode;
466: {
467: if (rcode == EX_OK)
468: return;
469: else if (rcode != EX_TEMPFAIL)
470: q->q_flags |= QBADADDR;
471: else if (curtime() > e->e_ctime + TimeOut)
472: {
473: extern char *pintvl();
474: char buf[MAXLINE];
475:
476: if (!bitset(EF_TIMEOUT, e->e_flags))
477: {
478: (void) sprintf(buf, "Cannot send message for %s",
479: pintvl(TimeOut, FALSE));
480: if (e->e_message != NULL)
481: free(e->e_message);
482: e->e_message = newstr(buf);
483: message(Arpa_Info, buf);
484: }
485: q->q_flags |= QBADADDR;
486: e->e_flags |= EF_TIMEOUT;
487: }
488: else
489: q->q_flags |= QQUEUEUP;
490: }
491: /*
492: ** DOFORK -- do a fork, retrying a couple of times on failure.
493: **
494: ** This MUST be a macro, since after a vfork we are running
495: ** two processes on the same stack!!!
496: **
497: ** Parameters:
498: ** none.
499: **
500: ** Returns:
501: ** From a macro??? You've got to be kidding!
502: **
503: ** Side Effects:
504: ** Modifies the ==> LOCAL <== variable 'pid', leaving:
505: ** pid of child in parent, zero in child.
506: ** -1 on unrecoverable error.
507: **
508: ** Notes:
509: ** I'm awfully sorry this looks so awful. That's
510: ** vfork for you.....
511: */
512:
513: # define NFORKTRIES 5
514: # ifdef VMUNIX
515: # define XFORK vfork
516: # else VMUNIX
517: # define XFORK fork
518: # endif VMUNIX
519:
520: # define DOFORK(fORKfN) \
521: {\
522: register int i;\
523: \
524: for (i = NFORKTRIES; --i >= 0; )\
525: {\
526: pid = fORKfN();\
527: if (pid >= 0)\
528: break;\
529: if (i > 0)\
530: sleep((unsigned) NFORKTRIES - i);\
531: }\
532: }
533: /*
534: ** DOFORK -- simple fork interface to DOFORK.
535: **
536: ** Parameters:
537: ** none.
538: **
539: ** Returns:
540: ** pid of child in parent.
541: ** zero in child.
542: ** -1 on error.
543: **
544: ** Side Effects:
545: ** returns twice, once in parent and once in child.
546: */
547:
548: dofork()
549: {
550: register int pid;
551:
552: DOFORK(fork);
553: return (pid);
554: }
555: /*
556: ** SENDOFF -- send off call to mailer & collect response.
557: **
558: ** Parameters:
559: ** e -- the envelope to mail.
560: ** m -- mailer descriptor.
561: ** pvp -- parameter vector to send to it.
562: ** ctladdr -- an address pointer controlling the
563: ** user/groupid etc. of the mailer.
564: **
565: ** Returns:
566: ** exit status of mailer.
567: **
568: ** Side Effects:
569: ** none.
570: */
571: static
572: sendoff(e, m, pvp, ctladdr)
573: register ENVELOPE *e;
574: MAILER *m;
575: char **pvp;
576: ADDRESS *ctladdr;
577: {
578: auto FILE *mfile;
579: auto FILE *rfile;
580: register int i;
581: int pid;
582:
583: /*
584: ** Create connection to mailer.
585: */
586:
587: pid = openmailer(m, pvp, ctladdr, FALSE, &mfile, &rfile);
588: if (pid < 0)
589: return (-1);
590:
591: /*
592: ** Format and send message.
593: */
594:
595: putfromline(mfile, m);
596: (*e->e_puthdr)(mfile, m, e);
597: putline("\n", mfile, m);
598: (*e->e_putbody)(mfile, m, e);
599: (void) fclose(mfile);
600:
601: i = endmailer(pid, pvp[0]);
602:
603: /* arrange a return receipt if requested */
604: if (e->e_receiptto != NULL && bitnset(M_LOCAL, m->m_flags))
605: {
606: e->e_flags |= EF_SENDRECEIPT;
607: /* do we want to send back more info? */
608: }
609:
610: return (i);
611: }
612: /*
613: ** ENDMAILER -- Wait for mailer to terminate.
614: **
615: ** We should never get fatal errors (e.g., segmentation
616: ** violation), so we report those specially. For other
617: ** errors, we choose a status message (into statmsg),
618: ** and if it represents an error, we print it.
619: **
620: ** Parameters:
621: ** pid -- pid of mailer.
622: ** name -- name of mailer (for error messages).
623: **
624: ** Returns:
625: ** exit code of mailer.
626: **
627: ** Side Effects:
628: ** none.
629: */
630:
631: endmailer(pid, name)
632: int pid;
633: char *name;
634: {
635: int st;
636:
637: /* in the IPC case there is nothing to wait for */
638: if (pid == 0)
639: return (EX_OK);
640:
641: /* wait for the mailer process to die and collect status */
642: st = waitfor(pid);
643: if (st == -1)
644: {
645: syserr("endmailer %s: wait", name);
646: return (EX_SOFTWARE);
647: }
648:
649: /* see if it died a horrid death */
650: if ((st & 0377) != 0)
651: {
652: syserr("mailer %s died with signal %o", name, st);
653: ExitStat = EX_TEMPFAIL;
654: return (EX_TEMPFAIL);
655: }
656:
657: /* normal death -- return status */
658: st = (st >> 8) & 0377;
659: return (st);
660: }
661: /*
662: ** OPENMAILER -- open connection to mailer.
663: **
664: ** Parameters:
665: ** m -- mailer descriptor.
666: ** pvp -- parameter vector to pass to mailer.
667: ** ctladdr -- controlling address for user.
668: ** clever -- create a full duplex connection.
669: ** pmfile -- pointer to mfile (to mailer) connection.
670: ** prfile -- pointer to rfile (from mailer) connection.
671: **
672: ** Returns:
673: ** pid of mailer ( > 0 ).
674: ** -1 on error.
675: ** zero on an IPC connection.
676: **
677: ** Side Effects:
678: ** creates a mailer in a subprocess.
679: */
680:
681: openmailer(m, pvp, ctladdr, clever, pmfile, prfile)
682: MAILER *m;
683: char **pvp;
684: ADDRESS *ctladdr;
685: bool clever;
686: FILE **pmfile;
687: FILE **prfile;
688: {
689: int pid;
690: int mpvect[2];
691: int rpvect[2];
692: FILE *mfile;
693: FILE *rfile;
694: extern FILE *fdopen();
695:
696: # ifdef DEBUG
697: if (tTd(11, 1))
698: {
699: printf("openmailer:");
700: printav(pvp);
701: }
702: # endif DEBUG
703: errno = 0;
704:
705: CurHostName = m->m_mailer;
706:
707: /*
708: ** Deal with the special case of mail handled through an IPC
709: ** connection.
710: ** In this case we don't actually fork. We must be
711: ** running SMTP for this to work. We will return a
712: ** zero pid to indicate that we are running IPC.
713: ** We also handle a debug version that just talks to stdin/out.
714: */
715:
716: #ifdef DEBUG
717: /* check for Local Person Communication -- not for mortals!!! */
718: if (strcmp(m->m_mailer, "[LPC]") == 0)
719: {
720: *pmfile = stdout;
721: *prfile = stdin;
722: return (0);
723: }
724: #endif DEBUG
725:
726: if (strcmp(m->m_mailer, "[IPC]") == 0)
727: {
728: #ifdef HOSTINFO
729: register STAB *st;
730: extern STAB *stab();
731: #endif HOSTINFO
732: #ifdef DAEMON
733: register int i, j;
734: register u_short port;
735:
736: CurHostName = pvp[1];
737: if (!clever)
738: syserr("non-clever IPC");
739: if (pvp[2] != NULL)
740: port = atoi(pvp[2]);
741: else
742: port = 0;
743: for (j = 0; j < Nmx; j++)
744: {
745: CurHostName = MxHosts[j];
746: #ifdef HOSTINFO
747: /* see if we have already determined that this host is fried */
748: st = stab(MxHosts[j], ST_HOST, ST_FIND);
749: if (st == NULL || st->s_host.ho_exitstat == EX_OK) {
750: if (j > 1)
751: message(Arpa_Info,
752: "Connecting to %s (%s)...",
753: MxHosts[j], m->m_name);
754: i = makeconnection(MxHosts[j], port, pmfile, prfile);
755: }
756: else
757: {
758: i = st->s_host.ho_exitstat;
759: errno = st->s_host.ho_errno;
760: }
761: #else HOSTINFO
762: i = makeconnection(MxHosts[j], port, pmfile, prfile);
763: #endif HOSTINFO
764: if (i != EX_OK)
765: {
766: #ifdef HOSTINFO
767: /* enter status of this host */
768: if (st == NULL)
769: st = stab(MxHosts[j], ST_HOST, ST_ENTER);
770: st->s_host.ho_exitstat = i;
771: st->s_host.ho_errno = errno;
772: #endif HOSTINFO
773: ExitStat = i;
774: continue;
775: }
776: else
777: return (0);
778: }
779: return (-1);
780: #else DAEMON
781: syserr("openmailer: no IPC");
782: return (-1);
783: #endif DAEMON
784: }
785:
786: /* create a pipe to shove the mail through */
787: if (pipe(mpvect) < 0)
788: {
789: syserr("openmailer: pipe (to mailer)");
790: return (-1);
791: }
792:
793: #ifdef SMTP
794: /* if this mailer speaks smtp, create a return pipe */
795: if (clever && pipe(rpvect) < 0)
796: {
797: syserr("openmailer: pipe (from mailer)");
798: (void) close(mpvect[0]);
799: (void) close(mpvect[1]);
800: return (-1);
801: }
802: #endif SMTP
803:
804: /*
805: ** Actually fork the mailer process.
806: ** DOFORK is clever about retrying.
807: **
808: ** Dispose of SIGCHLD signal catchers that may be laying
809: ** around so that endmail will get it.
810: */
811:
812: if (CurEnv->e_xfp != NULL)
813: (void) fflush(CurEnv->e_xfp); /* for debugging */
814: (void) fflush(stdout);
815: # ifdef SIGCHLD
816: (void) signal(SIGCHLD, SIG_DFL);
817: # endif SIGCHLD
818: DOFORK(XFORK);
819: /* pid is set by DOFORK */
820: if (pid < 0)
821: {
822: /* failure */
823: syserr("openmailer: cannot fork");
824: (void) close(mpvect[0]);
825: (void) close(mpvect[1]);
826: #ifdef SMTP
827: if (clever)
828: {
829: (void) close(rpvect[0]);
830: (void) close(rpvect[1]);
831: }
832: #endif SMTP
833: return (-1);
834: }
835: else if (pid == 0)
836: {
837: int i;
838: extern int DtableSize;
839:
840: /* child -- set up input & exec mailer */
841: /* make diagnostic output be standard output */
842: (void) signal(SIGINT, SIG_IGN);
843: (void) signal(SIGHUP, SIG_IGN);
844: (void) signal(SIGTERM, SIG_DFL);
845:
846: /* arrange to filter standard & diag output of command */
847: if (clever)
848: {
849: (void) close(rpvect[0]);
850: (void) close(1);
851: (void) dup(rpvect[1]);
852: (void) close(rpvect[1]);
853: }
854: else if (OpMode == MD_SMTP || HoldErrs)
855: {
856: /* put mailer output in transcript */
857: (void) close(1);
858: (void) dup(fileno(CurEnv->e_xfp));
859: }
860: (void) close(2);
861: (void) dup(1);
862:
863: /* arrange to get standard input */
864: (void) close(mpvect[1]);
865: (void) close(0);
866: if (dup(mpvect[0]) < 0)
867: {
868: syserr("Cannot dup to zero!");
869: _exit(EX_OSERR);
870: }
871: (void) close(mpvect[0]);
872: if (!bitnset(M_RESTR, m->m_flags))
873: {
874: if (ctladdr == NULL || ctladdr->q_uid == 0)
875: {
876: (void) setgid(DefGid);
877: (void) setuid(DefUid);
878: }
879: else
880: {
881: (void) setgid(ctladdr->q_gid);
882: (void) setuid(ctladdr->q_uid);
883: }
884: }
885:
886: /* arrange for all the files to be closed */
887: for (i = 3; i < DtableSize; i++)
888: (void) ioctl(i, FIOCLEX, 0);
889:
890: /* try to execute the mailer */
891: execve(m->m_mailer, pvp, UserEnviron);
892: syserr("Cannot exec %s", m->m_mailer);
893: if (m == LocalMailer || errno == EIO || errno == EAGAIN ||
894: errno == ENOMEM || errno == EPROCLIM)
895: _exit(EX_TEMPFAIL);
896: else
897: _exit(EX_UNAVAILABLE);
898: }
899:
900: /*
901: ** Set up return value.
902: */
903:
904: (void) close(mpvect[0]);
905: mfile = fdopen(mpvect[1], "w");
906: if (clever)
907: {
908: (void) close(rpvect[1]);
909: rfile = fdopen(rpvect[0], "r");
910: }
911:
912: *pmfile = mfile;
913: *prfile = rfile;
914:
915: return (pid);
916: }
917: /*
918: ** GIVERESPONSE -- Interpret an error response from a mailer
919: **
920: ** Parameters:
921: ** stat -- the status code from the mailer (high byte
922: ** only; core dumps must have been taken care of
923: ** already).
924: ** m -- the mailer descriptor for this mailer.
925: **
926: ** Returns:
927: ** none.
928: **
929: ** Side Effects:
930: ** Errors may be incremented.
931: ** ExitStat may be set.
932: */
933:
934: giveresponse(stat, m, e)
935: int stat;
936: register MAILER *m;
937: ENVELOPE *e;
938: {
939: register char *statmsg;
940: extern char *SysExMsg[];
941: register int i;
942: extern int N_SysEx, h_errno;
943: char buf[MAXLINE];
944:
945: #ifdef lint
946: if (m == NULL)
947: return;
948: #endif lint
949:
950: /*
951: ** Compute status message from code.
952: */
953:
954: i = stat - EX__BASE;
955: if (stat == 0)
956: statmsg = "250 Sent";
957: else if (i < 0 || i > N_SysEx)
958: {
959: (void) sprintf(buf, "554 unknown mailer error %d", stat);
960: stat = EX_UNAVAILABLE;
961: statmsg = buf;
962: }
963: else if (stat == EX_TEMPFAIL)
964: {
965: (void) strcpy(buf, SysExMsg[i]);
966: if (h_errno == TRY_AGAIN)
967: {
968: extern char *errstring();
969:
970: statmsg = errstring(h_errno+MAX_ERRNO);
971: }
972: else
973: {
974: if (errno != 0)
975: {
976: extern char *errstring();
977:
978: statmsg = errstring(errno);
979: }
980: else
981: {
982: #ifdef SMTP
983: extern char SmtpError[];
984:
985: statmsg = SmtpError;
986: #else SMTP
987: statmsg = NULL;
988: #endif SMTP
989: }
990: }
991: if (statmsg != NULL && statmsg[0] != '\0')
992: {
993: (void) strcat(buf, ": ");
994: (void) strcat(buf, statmsg);
995: }
996: statmsg = buf;
997: }
998: else
999: {
1000: statmsg = SysExMsg[i];
1001: }
1002:
1003: /*
1004: ** Print the message as appropriate
1005: */
1006:
1007: if (stat == EX_OK || stat == EX_TEMPFAIL)
1008: message(Arpa_Info, &statmsg[4]);
1009: else
1010: {
1011: Errors++;
1012: usrerr(statmsg);
1013: }
1014:
1015: /*
1016: ** Final cleanup.
1017: ** Log a record of the transaction. Compute the new
1018: ** ExitStat -- if we already had an error, stick with
1019: ** that.
1020: */
1021:
1022: if (LogLevel > ((stat == 0 || stat == EX_TEMPFAIL) ? 3 : 2))
1023: logdelivery(&statmsg[4]);
1024:
1025: if (stat != EX_TEMPFAIL)
1026: setstat(stat);
1027: if (stat != EX_OK)
1028: {
1029: if (e->e_message != NULL)
1030: free(e->e_message);
1031: e->e_message = newstr(&statmsg[4]);
1032: }
1033: errno = 0;
1034: h_errno = 0;
1035: }
1036: /*
1037: ** LOGDELIVERY -- log the delivery in the system log
1038: **
1039: ** Parameters:
1040: ** stat -- the message to print for the status
1041: **
1042: ** Returns:
1043: ** none
1044: **
1045: ** Side Effects:
1046: ** none
1047: */
1048:
1049: logdelivery(stat)
1050: char *stat;
1051: {
1052: extern char *pintvl();
1053:
1054: # ifdef LOG
1055: syslog(LOG_INFO, "%s: to=%s, delay=%s, stat=%s", CurEnv->e_id,
1056: CurEnv->e_to, pintvl(curtime() - CurEnv->e_ctime, TRUE), stat);
1057: # endif LOG
1058: }
1059: /*
1060: ** PUTFROMLINE -- output a UNIX-style from line (or whatever)
1061: **
1062: ** This can be made an arbitrary message separator by changing $l
1063: **
1064: ** One of the ugliest hacks seen by human eyes is contained herein:
1065: ** UUCP wants those stupid "remote from <host>" lines. Why oh why
1066: ** does a well-meaning programmer such as myself have to deal with
1067: ** this kind of antique garbage????
1068: **
1069: ** Parameters:
1070: ** fp -- the file to output to.
1071: ** m -- the mailer describing this entry.
1072: **
1073: ** Returns:
1074: ** none
1075: **
1076: ** Side Effects:
1077: ** outputs some text to fp.
1078: */
1079:
1080: putfromline(fp, m)
1081: register FILE *fp;
1082: register MAILER *m;
1083: {
1084: char *template = "\001l\n";
1085: char buf[MAXLINE];
1086:
1087: if (bitnset(M_NHDR, m->m_flags))
1088: return;
1089:
1090: # ifdef UGLYUUCP
1091: if (bitnset(M_UGLYUUCP, m->m_flags))
1092: {
1093: char *bang;
1094: char xbuf[MAXLINE];
1095:
1096: expand("\001g", buf, &buf[sizeof buf - 1], CurEnv);
1097: bang = index(buf, '!');
1098: if (bang == NULL)
1099: syserr("No ! in UUCP! (%s)", buf);
1100: else
1101: {
1102: *bang++ = '\0';
1103: (void) sprintf(xbuf, "From %s \001d remote from %s\n", bang, buf);
1104: template = xbuf;
1105: }
1106: }
1107: # endif UGLYUUCP
1108: expand(template, buf, &buf[sizeof buf - 1], CurEnv);
1109: putline(buf, fp, m);
1110: }
1111: /*
1112: ** PUTBODY -- put the body of a message.
1113: **
1114: ** Parameters:
1115: ** fp -- file to output onto.
1116: ** m -- a mailer descriptor to control output format.
1117: ** e -- the envelope to put out.
1118: **
1119: ** Returns:
1120: ** none.
1121: **
1122: ** Side Effects:
1123: ** The message is written onto fp.
1124: */
1125:
1126: putbody(fp, m, e)
1127: FILE *fp;
1128: MAILER *m;
1129: register ENVELOPE *e;
1130: {
1131: char buf[MAXLINE];
1132:
1133: /*
1134: ** Output the body of the message
1135: */
1136:
1137: if (e->e_dfp == NULL)
1138: {
1139: if (e->e_df != NULL)
1140: {
1141: e->e_dfp = fopen(e->e_df, "r");
1142: if (e->e_dfp == NULL)
1143: syserr("Cannot open %s", e->e_df);
1144: }
1145: else
1146: putline("<<< No Message Collected >>>", fp, m);
1147: }
1148: if (e->e_dfp != NULL)
1149: {
1150: rewind(e->e_dfp);
1151: while (!ferror(fp) && fgets(buf, sizeof buf, e->e_dfp) != NULL)
1152: {
1153: if (buf[0] == 'F' && bitnset(M_ESCFROM, m->m_flags) &&
1154: strncmp(buf, "From", 4) == 0)
1155: (void) putc('>', fp);
1156: putline(buf, fp, m);
1157: }
1158:
1159: if (ferror(e->e_dfp))
1160: {
1161: syserr("putbody: read error");
1162: ExitStat = EX_IOERR;
1163: }
1164: }
1165:
1166: (void) fflush(fp);
1167: if (ferror(fp) && errno != EPIPE)
1168: {
1169: syserr("putbody: write error");
1170: ExitStat = EX_IOERR;
1171: }
1172: errno = 0;
1173: }
1174: /*
1175: ** MAILFILE -- Send a message to a file.
1176: **
1177: ** If the file has the setuid/setgid bits set, but NO execute
1178: ** bits, sendmail will try to become the owner of that file
1179: ** rather than the real user. Obviously, this only works if
1180: ** sendmail runs as root.
1181: **
1182: ** This could be done as a subordinate mailer, except that it
1183: ** is used implicitly to save messages in ~/dead.letter. We
1184: ** view this as being sufficiently important as to include it
1185: ** here. For example, if the system is dying, we shouldn't have
1186: ** to create another process plus some pipes to save the message.
1187: **
1188: ** Parameters:
1189: ** filename -- the name of the file to send to.
1190: ** ctladdr -- the controlling address header -- includes
1191: ** the userid/groupid to be when sending.
1192: **
1193: ** Returns:
1194: ** The exit code associated with the operation.
1195: **
1196: ** Side Effects:
1197: ** none.
1198: */
1199:
1200: mailfile(filename, ctladdr)
1201: char *filename;
1202: ADDRESS *ctladdr;
1203: {
1204: register FILE *f;
1205: register int pid;
1206:
1207: /*
1208: ** Fork so we can change permissions here.
1209: ** Note that we MUST use fork, not vfork, because of
1210: ** the complications of calling subroutines, etc.
1211: */
1212:
1213: DOFORK(fork);
1214:
1215: if (pid < 0)
1216: return (EX_OSERR);
1217: else if (pid == 0)
1218: {
1219: /* child -- actually write to file */
1220: struct stat stb;
1221:
1222: (void) signal(SIGINT, SIG_DFL);
1223: (void) signal(SIGHUP, SIG_DFL);
1224: (void) signal(SIGTERM, SIG_DFL);
1225: (void) umask(OldUmask);
1226: if (stat(filename, &stb) < 0)
1227: {
1228: errno = 0;
1229: stb.st_mode = 0666;
1230: }
1231: if (bitset(0111, stb.st_mode))
1232: exit(EX_CANTCREAT);
1233: if (ctladdr == NULL)
1234: ctladdr = &CurEnv->e_from;
1235: if (!bitset(S_ISGID, stb.st_mode) || setgid(stb.st_gid) < 0)
1236: {
1237: if (ctladdr->q_uid == 0)
1238: (void) setgid(DefGid);
1239: else
1240: (void) setgid(ctladdr->q_gid);
1241: }
1242: if (!bitset(S_ISUID, stb.st_mode) || setuid(stb.st_uid) < 0)
1243: {
1244: if (ctladdr->q_uid == 0)
1245: (void) setuid(DefUid);
1246: else
1247: (void) setuid(ctladdr->q_uid);
1248: }
1249: f = dfopen(filename, "a");
1250: if (f == NULL)
1251: exit(EX_CANTCREAT);
1252:
1253: putfromline(f, ProgMailer);
1254: (*CurEnv->e_puthdr)(f, ProgMailer, CurEnv);
1255: putline("\n", f, ProgMailer);
1256: (*CurEnv->e_putbody)(f, ProgMailer, CurEnv);
1257: putline("\n", f, ProgMailer);
1258: (void) fclose(f);
1259: (void) fflush(stdout);
1260:
1261: /* reset ISUID & ISGID bits for paranoid systems */
1262: (void) chmod(filename, (int) stb.st_mode);
1263: exit(EX_OK);
1264: /*NOTREACHED*/
1265: }
1266: else
1267: {
1268: /* parent -- wait for exit status */
1269: int st;
1270:
1271: st = waitfor(pid);
1272: if ((st & 0377) != 0)
1273: return (EX_UNAVAILABLE);
1274: else
1275: return ((st >> 8) & 0377);
1276: }
1277: }
1278: /*
1279: ** SENDALL -- actually send all the messages.
1280: **
1281: ** Parameters:
1282: ** e -- the envelope to send.
1283: ** mode -- the delivery mode to use. If SM_DEFAULT, use
1284: ** the current SendMode.
1285: **
1286: ** Returns:
1287: ** none.
1288: **
1289: ** Side Effects:
1290: ** Scans the send lists and sends everything it finds.
1291: ** Delivers any appropriate error messages.
1292: ** If we are running in a non-interactive mode, takes the
1293: ** appropriate action.
1294: */
1295:
1296: sendall(e, mode)
1297: ENVELOPE *e;
1298: char mode;
1299: {
1300: register ADDRESS *q;
1301: bool oldverbose;
1302: int pid;
1303:
1304: /* determine actual delivery mode */
1305: if (mode == SM_DEFAULT)
1306: {
1307: extern bool shouldqueue();
1308:
1309: if (shouldqueue(e->e_msgpriority))
1310: mode = SM_QUEUE;
1311: else
1312: mode = SendMode;
1313: }
1314:
1315: #ifdef DEBUG
1316: if (tTd(13, 1))
1317: {
1318: printf("\nSENDALL: mode %c, sendqueue:\n", mode);
1319: printaddr(e->e_sendqueue, TRUE);
1320: }
1321: #endif DEBUG
1322:
1323: /*
1324: ** Do any preprocessing necessary for the mode we are running.
1325: ** Check to make sure the hop count is reasonable.
1326: ** Delete sends to the sender in mailing lists.
1327: */
1328:
1329: CurEnv = e;
1330:
1331: if (e->e_hopcount > MAXHOP)
1332: {
1333: syserr("sendall: too many hops (%d max)", MAXHOP);
1334: return;
1335: }
1336:
1337: if (!MeToo)
1338: {
1339: extern ADDRESS *recipient();
1340:
1341: e->e_from.q_flags |= QDONTSEND;
1342: (void) recipient(&e->e_from, &e->e_sendqueue);
1343: }
1344:
1345: # ifdef QUEUE
1346: if ((mode == SM_QUEUE || mode == SM_FORK ||
1347: (mode != SM_VERIFY && SuperSafe)) &&
1348: !bitset(EF_INQUEUE, e->e_flags))
1349: queueup(e, TRUE, mode == SM_QUEUE);
1350: #endif QUEUE
1351:
1352: oldverbose = Verbose;
1353: switch (mode)
1354: {
1355: case SM_VERIFY:
1356: Verbose = TRUE;
1357: break;
1358:
1359: case SM_QUEUE:
1360: e->e_flags |= EF_INQUEUE|EF_KEEPQUEUE;
1361: return;
1362:
1363: case SM_FORK:
1364: if (e->e_xfp != NULL)
1365: (void) fflush(e->e_xfp);
1366: pid = fork();
1367: if (pid < 0)
1368: {
1369: mode = SM_DELIVER;
1370: break;
1371: }
1372: else if (pid > 0)
1373: {
1374: /* be sure we leave the temp files to our child */
1375: e->e_id = e->e_df = NULL;
1376: return;
1377: }
1378:
1379: /* double fork to avoid zombies */
1380: if (fork() > 0)
1381: exit(EX_OK);
1382:
1383: /* be sure we are immune from the terminal */
1384: disconnect(FALSE);
1385:
1386: break;
1387: }
1388:
1389: /*
1390: ** Run through the list and send everything.
1391: */
1392:
1393: for (q = e->e_sendqueue; q != NULL; q = q->q_next)
1394: {
1395: if (mode == SM_VERIFY)
1396: {
1397: e->e_to = q->q_paddr;
1398: if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
1399: message(Arpa_Info, "deliverable");
1400: }
1401: else
1402: (void) deliver(e, q);
1403: }
1404: Verbose = oldverbose;
1405:
1406: /*
1407: ** Now run through and check for errors.
1408: */
1409:
1410: if (mode == SM_VERIFY)
1411: return;
1412:
1413: for (q = e->e_sendqueue; q != NULL; q = q->q_next)
1414: {
1415: register ADDRESS *qq;
1416:
1417: # ifdef DEBUG
1418: if (tTd(13, 3))
1419: {
1420: printf("Checking ");
1421: printaddr(q, FALSE);
1422: }
1423: # endif DEBUG
1424:
1425: /* only send errors if the message failed */
1426: if (!bitset(QBADADDR, q->q_flags))
1427: continue;
1428:
1429: /* we have an address that failed -- find the parent */
1430: for (qq = q; qq != NULL; qq = qq->q_alias)
1431: {
1432: char obuf[MAXNAME + 6];
1433: extern char *aliaslookup();
1434:
1435: /* we can only have owners for local addresses */
1436: if (!bitnset(M_LOCAL, qq->q_mailer->m_flags))
1437: continue;
1438:
1439: /* see if the owner list exists */
1440: (void) strcpy(obuf, "owner-");
1441: if (strncmp(qq->q_user, "owner-", 6) == 0)
1442: (void) strcat(obuf, "owner");
1443: else
1444: (void) strcat(obuf, qq->q_user);
1445: if (aliaslookup(obuf) == NULL)
1446: continue;
1447:
1448: # ifdef DEBUG
1449: if (tTd(13, 4))
1450: printf("Errors to %s\n", obuf);
1451: # endif DEBUG
1452:
1453: /* owner list exists -- add it to the error queue */
1454: sendtolist(obuf, (ADDRESS *) NULL, &e->e_errorqueue);
1455: ErrorMode = EM_MAIL;
1456: break;
1457: }
1458:
1459: /* if we did not find an owner, send to the sender */
1460: if (qq == NULL && bitset(QBADADDR, q->q_flags))
1461: sendtolist(e->e_from.q_paddr, qq, &e->e_errorqueue);
1462: }
1463:
1464: if (mode == SM_FORK)
1465: finis();
1466: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.