]>
diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/zotnet/mf/mmdfI/src/uucp/rmail.c
1 #define MFDEBUG /* temporarily */
3 static char Id
[] = "@(#)$Id: rmail.c,v 1.2 1993/08/25 17:32:49 jromine Exp $";
16 * Developed from the Berkeley mail program of the same name
17 * by Mike Obrien at RAND to run with the MMDF mail system.
18 * Rewritten by Doug Kingston, US Army Ballistics Research Laboratory
19 * Hacked a lot by Steve Bellovin (smb@unc)
21 * This program runs SETUID to root so that it can set effective and
22 * real [ug]ids to mmdflogin.
24 * 27-Oct-82 Marshall T. Rose <mrose%uci@rand-relay>
25 * Support proper munging by using the UCI mail filtering
26 * routines (enabled by #ifdef MF)
27 * Also use ll_log() package (enabled by #ifdef LOG)
29 * 17-Oct-83 Marshall T. Rose <mrose%uci@rand-relay>
30 * New interfacing. Remove the #ifdef:s
34 #define NAMESZ 64 /* Limit on component name size */
42 char *Fromtmp
= "/tmp/rml.f.XXXXXX";
43 char *Msgtmp
= "/tmp/rml.m.XXXXXX";
44 char *Errtmp
= "/tmp/rml.e.XXXXXX";
45 char *Okhosts
= "/usr/mmdf/table/rmail.ok";
46 char *Okdests
= "/usr/mmdf/table/rmail.okdests";
48 extern char cmddfldir
[];
49 extern char logdfldir
[];
50 extern char mmdflogin
[];
51 extern char pathsubmit
[];
52 extern char sitesignature
[];
53 extern char supportaddr
[];
54 extern struct ll_struct chanlog
;
56 char *dupfpath (), *index(), *rindex();
57 struct passwd
*getpwnam(), *getpwuid();
62 struct ll_struct
*logptr
= &chanlog
;
64 FILE *fromf
; /* temporary out for colon-less UUCP "From" lines */
65 FILE *msgf
; /* temporary out for message text */
66 FILE *mmdf
; /* filtered mail file */
67 FILE *pipef
; /* output to "submit" or "uux" */
68 char date
[LINESIZE
]; /* date of origination from uucp header */
69 char from
[LINESIZE
]; /* accumulated path of sender */
70 char origsys
[NAMESZ
]; /* originating system */
71 char origpath
[LINESIZE
];/* path from us to originating system */
72 char usrfrm
[LINESIZE
];
73 char Mailsys
[LINESIZE
];
74 int pbroke
; /* broken-pipe flag */
75 int rtnflag
; /* note was sent back */
84 char fromwhom
[NAMESZ
]; /* user on remote system */
86 char linebuf
[LINESIZE
]; /* scratchpad */
87 char sys
[NAMESZ
]; /* an element in the uucp path */
94 fprintf(stderr
, "Usage: rmail user [user ...]\n");
99 ll_hdinit (logptr
, "RM");
100 logptr
-> ll_file
= dupfpath (logptr
-> ll_file
, logdfldir
);
102 if ((pw
= getpwnam (mmdflogin
)) == NULL
) {
103 fprintf (stderr
, "Cannot find mmdflogin\n");
109 sprintf (Mailsys
, "%s <%s@%s>",
110 sitesignature
, mmdflogin
, LocalName ());
114 { /* BE VERY SURE... */
117 for (i
= fileno (stdout
); i
<= HIGHFD
; i
++)
121 /* create file to hold stderr output. We first open some */
122 /* null file to make sure stdout is taken. If stdin isn't */
123 /* open either, we've got so much trouble it isn't even worth */
124 /* worrying about a little more */
125 open("/dev/null", 0);
127 if (freopen(Errtmp
, "w", stderr
) == NULL
) {
128 fprintf(stderr
, "Can't create %s\n", Errtmp
);
129 ll_log (logptr
, LLOGFAT
, "Unable to create '%s'",
133 dup2 (fileno (stderr
), fileno (stdout
));
135 /* Create temp file for rest of message */
137 if ((msgf
=fdopen(creat(Msgtmp
, Tmpmode
), "w")) == NULL
) {
138 fprintf(stderr
, "Can't create %s\n", Msgtmp
);
139 ll_log (logptr
, LLOGFAT
, "Unable to create '%s'",
144 /* create temp file for colon-less UUCP "From" lines */
146 if ((fromf
=fdopen(creat(Fromtmp
, Tmpmode
), "w")) == NULL
) {
147 fprintf(stderr
, "Can't create %s\n", Fromtmp
);
148 ll_log (logptr
, LLOGFAT
, "Unable to create '%s'",
156 if( fgets(linebuf
, sizeof linebuf
, stdin
) == NULL
)
158 if( strncmp(linebuf
, "From ", 5)
159 && strncmp(linebuf
, ">From ", 6) )
162 if (linebuf
[0] != '>')
164 fputs(linebuf
, fromf
); /* Save, we may forward via UUCP */
165 cp
= index (linebuf
, ' '); /* start of name */
167 cp
= index (cp
, ' '); /* cp at end of name */
168 *cp
++ = 0; /* term. name, cp at date */
169 strcpy (fromwhom
, fromptr
);
170 strncpy (date
, cp
, 24); /* Mon Nov 10 23:12:09 1981 */
173 cp
= index(cp
+1, 'r');
175 cp
= rindex(fromwhom
, '!');
179 p
= rindex(fromwhom
, '!');
180 if (p
!= NULL
) strcpy(origsys
, p
+1);
181 else strcpy(origsys
, fromwhom
);
182 strcat(from
, fromwhom
);
184 strcpy(fromwhom
, cp
+1);
187 strcpy (sys
, SystemName ());
189 strcpy (origsys
, sys
);
193 if (strncmp(cp
, "remote from ", 12) == 0)
197 sscanf(cp
, "remote from %s", sys
);
199 strcpy(origsys
, sys
); /* Save for quick ref. */
203 if( fromwhom
[0] == '\0' ) /* No from line, illegal */
208 strcpy (origpath
, from
);
209 strcat (from
, fromwhom
);
210 mf_get_addr (from
, usrfrm
);
211 if ((cp
= rindex (usrfrm
, '<')) != NULL
) {
212 strcpy (usrfrm
, ++cp
);/* sigh */
213 if ((cp
= rindex (usrfrm
, '>')) != NULL
)
216 if (usrfrm
[0] == NULL
)
217 sprintf (usrfrm
, "%s!%s%%%s@%s",
218 SystemName (), from
, UucpChan (), LocalName ());
219 ll_log (logptr
, LLOGGEN
, "Rmail from '%s' (%s)", from
, usrfrm
);
220 fputs (linebuf
, msgf
);
221 if (rp_isbad (txtcpy (stdin
, msgf
)))
222 fputs ("\n *** Problem during receipt from UUCP ***\n", msgf
);
224 freopen (Msgtmp
, "r", msgf
);
225 freopen (Fromtmp
, "r", fromf
);
231 for (argv
++; --argc
> 0; ) {
238 signal(SIGPIPE
, brpipe
);
239 if (rp_isbad(deliver(*argv
++)) && !rtnflag
)
243 /* Send back a copy if something nasty happened. For now, we use */
244 /* a real kludge -- we see if we noted some error, or if we find */
245 /* anything written to stderr.... */
249 if (cpyback
) {rcpy();zcpy();}
259 * deliver() -- Handle all deliveries be they returns, automatic
260 * copies, or the real thing. Based on the address
261 * the letter is accepted or returned with a copy
262 * to the system administrators
264 * main() has set up the "from" string and the
268 " --------------- End of Returned Mail ---------------\n";
275 char linebuf
[LINESIZE
];
276 char tmpbuf
[LINESIZE
];
278 switch (adrcheck (to
)) {
280 ll_log (logptr
, LLOGGEN
, "Rmail to '%s' via MMDF", to
);
281 if (rp_isbad (replyval
=
282 xsubmit (NULL
, usrfrm
, NULL
, NULL
, to
)))
285 if (mf_get_msg () == NOTOK
)
287 replyval
= txtcpy (mmdf
, pipef
);
289 i
= (pclose(pipef
) >> 8 ) & 0xff;
290 if (rp_isgood(replyval
)) replyval
= i
;
295 ll_log (logptr
, LLOGGEN
, "Rmail to '%s' via UUCP", to
);
296 if (rp_isbad (replyval
= xuucp(from
, to
)))
298 replyval
= txtcpy(msgf
, pipef
);
300 i
= (pclose(pipef
) >> 8 ) & 0xff;
301 if (rp_isgood(replyval
)) replyval
= (i
== 0 ? RP_OK
: RP_LIO
);
309 ll_log (logptr
, LLOGGEN
, "Illegal Rmail to '%s'", to
);
310 switch (adrcheck (from
)) {
313 replyval
= xsubmit (dtimenow (), Mailsys
,
314 from
, supportaddr
, from
);
316 txtcpy(fromf
, pipef
);
318 fputs (rtnend
, pipef
);
320 i
= (pclose(pipef
) >> 8 ) & 0xff;
321 if (rp_isgood(replyval
)) replyval
= i
;
326 replyval
= xuucp (mmdflogin
, from
);
327 if (rp_isbad (replyval
))
329 fprintf (pipef
, "To: %s\n", from
);
330 fprintf (pipef
, "Cc: %s\n", supportaddr
);
332 txtcpy(fromf
, pipef
);
334 fputs (rtnend
, pipef
);
336 i
= (pclose(pipef
) >> 8 ) & 0xff;
337 if (rp_isgood(replyval
))
338 replyval
= (i
== 0 ? RP_OK
: RP_LIO
);
343 /* And now for the mail overseer's copy */
345 ll_log (logptr
, LLOGGEN
, "Notifying %s", supportaddr
);
349 replyval
= xsubmit (dtimenow (), Mailsys
,
350 usrfrm
, supportaddr
, supportaddr
);
351 if (rp_isbad (replyval
))
354 txtcpy (fromf
, pipef
);
355 txtcpy (msgf
, pipef
);
356 fputs (rtnend
, pipef
);
358 i
= (pclose(pipef
) >> 8 ) & 0xff;
359 if (rp_isgood(replyval
)) replyval
= i
;
368 adrcheck (adr
) /* Gateway to Arpanet? */
377 if ((adrxp
= seekadrx (adr
)) == NULL
)
379 strcpy (err
, adrxp
-> err
? adrxp
-> err
: "");
380 strcpy (host
, adrxp
-> host
? adrxp
-> host
: "");
381 strcpy (mbox
, adrxp
-> mbox
? adrxp
-> mbox
: "");
382 while (seekadrx (NULL
))
385 if (err
[0] || mbox
[0] == NULL
)
387 if (index (mbox
, '!') || host
[0] == NULL
)
389 if (rp_isgood (lookup (origsys
, Okhosts
)))
391 if (index (host
, '@') || rp_isbad (okhost (host
)))
398 okhost(host
) /* Host permitted to use mail facilities? */
401 if (rp_isgood (lookup (origsys
, Okhosts
)))
402 return (RP_OK
); /* Fully privledged originator */
403 if (rp_isgood (lookup (host
, Okhosts
)))
404 return (RP_OK
); /* Fully privledged dest */
405 if (rp_isgood (lookup (host
, Okdests
)))
406 return (RP_OK
); /* Unrestricted Dest. Host, OK */
407 return(RP_NO
); /* Not permitted; must be bad */
413 * lookup() -- This lookup function looks for strings which
414 * must be the first string on a line. Sorry Dave (dhc)
415 * but the MMDF channel functions are too specific
416 * to be easily used here without much kludging.
419 /*****************************************
420 **** Can this be a call to a MMDF function??
421 **** Remember I have the RHOSTs table and the OKHOSTS table.
422 ******************************************/
428 char entry
[LINESIZE
];
431 if ((lookf
= fopen (where
, "r")) == NULL
)
432 return (RP_NO
); /* Unknown problem */
433 while (fgets (entry
, sizeof entry
, lookf
) != NULL
) {
435 while (*cp
!= '\n' && *cp
!= ' ' && *cp
!= '\t')
438 if (lexequ (what
, entry
)) {
450 char *rtnmessage
[] = {
451 " Your message has been intercepted trying to access\n",
452 "a restricted access host (e.g. an ARPANET host). A copy\n",
453 "of your message has been sent to the system administrators.\n",
454 "The text of your message follows.\n\n",
455 " --------------- Returned Mail Follows --------------\n",
464 fprintf (pipef
, "Subject: Illegal Address (%s)\n\n", badadr
);
465 for (cpp
= rtnmessage
; *cpp
; cpp
++)
475 while (!pbroke
&& (nread
= fread (buffer
, sizeof (*buffer
), BUFSIZ
, frm
)) > 0)
476 fwrite (buffer
, sizeof (*buffer
), nread
, to
);
477 return (ferror (frm
) ? RP_LIO
: RP_OK
);
482 xsubmit (date
, from
, to
, cc
, realto
)
483 char *date
, *from
, *to
, *cc
, *realto
;
485 char cmdstr
[LINESIZE
],
488 getfpath (pathsubmit
, cmddfldir
, submit
);
489 sprintf (cmdstr
, "%s '-mlti%s*'", submit
, UucpChan ());
492 if ((pipef
= popen (cmdstr
, "w")) == NULL
)
496 printf ("%s\n", cmdstr
);
499 fprintf (pipef
, "%s\n%s\n!\n", from
, realto
);
502 fprintf (pipef
, "Date: %s\n", date
);
503 fprintf (pipef
, "From: %s\n", from
);
506 fprintf (pipef
, "To: %s", to
);
508 fputc ('\n', pipef
);/* Explicit host specified */
510 fprintf (pipef
, "@%s\n", LocalName ());
513 fprintf (pipef
, "Cc: %s\n", cc
);
524 char cmdstr
[LINESIZE
];
526 sprintf (cmdstr
, "/etc/delivermail -r%s -ep -m -s -i %s", from
, to
);
529 if ((pipef
= popen (cmdstr
, "w")) == NULL
)
533 printf ("%s\n", cmdstr
);
541 brpipe() /* catch broken-pipe signals */
543 signal(SIGPIPE
, SIG_IGN
);
547 char *oopsmessage
[] = {
548 "\n\n\tThe system administrators (%s) have been informed of the\n",
549 "problem, but have not been given a copy of your message.\n",
561 ll_log (logptr
, LLOGGEN
, "Advising %s of failure as %s...", from
, usrfrm
);
563 sprintf (buffer
, "Problems sending mail:\n\n");
564 if (ml_1adr (NO
, NO
, sitesignature
, "Problems sending mail", usrfrm
)
569 if ((fp
= fopen (Errtmp
, "r")) != NULL
) {
571 if (ftell (fp
) == 0L)
572 fprintf (pipef
, "\tunknown problem\n");
576 ml_txt ("\tunknown problem\n");
578 for (i
= 0; oopsmessage
[i
]; i
++) {
579 sprintf (message
, oopsmessage
[i
], supportaddr
);
582 fprintf (pipef
, "\n\nReturned message follows:\n\n---------------\n\n");
588 if (ml_end (OK
) != OK
) {
592 if (cp
= index (buffer
, '\n'))
594 ll_log (logptr
, LLOGFAT
, "Unable to post failure notice");
595 ll_log (logptr
, LLOGFAT
, "info: %s", buffer
);
605 ll_log (logptr
, LLOGGEN
, "Advising %s of failure...", supportaddr
);
607 sprintf (buffer
, "Problems sending mail for %s (aka %s):\n\n",
609 if (ml_1adr (NO
, NO
, sitesignature
, "Problems sending mail", supportaddr
)
614 if ((fp
= fopen (Errtmp
, "r")) != NULL
) {
616 if (ftell (fp
) == 0L)
617 fprintf (pipef
, "\tunknown problem\n");
621 ml_txt ("\tunable to open error file\n");
623 if (ml_end (OK
) != OK
) {
627 if (cp
= index (buffer
, '\n'))
629 ll_log (logptr
, LLOGFAT
, "Unable to post failure notice");
630 ll_log (logptr
, LLOGFAT
, "info: %s", buffer
);
649 strcpy (tmpfil
, "/tmp/rmailXXXXXX");
650 unlink (mktemp (tmpfil
));
651 if ((fd
= creat (tmpfil
, Tmpmode
)) == NOTOK
)
654 if ((fd
= open (tmpfil
, 2)) == NOTOK
)
656 if ((out
= fdopen (fd
, "w")) == NULL
) {
660 if ((td
= dup (fd
)) == NOTOK
) {
665 fprintf (out
, "From %s %s\n", from
, date
);
666 if (rp_isbad (txtcpy (msgf
, out
))) {
672 lseek (td
, (off_t
)0, 0);
674 strcpy (mmdfil
, "/tmp/mmdfXXXXXX");
675 unlink (mktemp (mmdfil
));
676 if ((fd
= creat (mmdfil
, Tmpmode
)) == NOTOK
) {
681 if ((fd
= open (mmdfil
, 2)) == NOTOK
) {
686 if ((md
= dup (fd
)) == NOTOK
) {
695 switch (i
= uucp_to_mmdf (td
, fd
, TRUE
)) {
697 lseek (md
, (off_t
)0, 0);
698 if ((mmdf
= fdopen (md
, "r")) != NULL
)
704 sprintf (buffer
, "rmail(%d) filtering failed(%d)\n",
706 if (ml_1adr (NO
, NO
, sitesignature
, "MF Failure", supportaddr
)
711 lseek (td
, (off_t
)0, 0);
712 if ((md
= dup (td
)) == NOTOK
)
713 ml_txt ("unable to dup() descriptor for message copy\n");
715 if ((fp
= fdopen (md
, "r")) == NULL
) {
716 ml_txt ("unable to fdopen() descriptor for message copy\n");
720 ml_txt ("\n --Message Follows--\n");
725 if (ml_end (OK
) != OK
) {
729 if (cp
= index (buffer
, '\n'))
731 ll_log (logptr
, LLOGFAT
, "Unable to post failure notice");
732 ll_log (logptr
, LLOGFAT
, "info: %s", buffer
);
748 mf_get_addr (from
, to
)
756 if ((adrxp
= seekadrx (from
)) == NULL
)
758 addr_convert (adrxp
, to
, TRUE
);
759 while (seekadrx (NULL
))