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