home *** CD-ROM | disk | FTP | other *** search
- /*
- * authorise - sendmail authorisation program
- *
- * Given a channel name, sender address and recipient address or
- * host, it matches these against entries in an authorisation
- * file to see if permission is granted to send the mail.
- *
- * If successful, the mailer interface is called; else the
- * appropriate error status is returned to sendmail.
- *
- * Written by Jim Crammond. <jac@ic.doc> 5/87
- */
- #include <stdio.h>
- #include <sysexits.h>
-
- #define AUTHFILE "/usr/lib/authorisations"
-
- #define CHANSIZE 64
- #define ADDRSIZE 256
- #define LINESIZE 1024
-
- char a_chan[CHANSIZE];
- char a_from[ADDRSIZE];
- char a_to[ADDRSIZE];
-
- char *authfile = AUTHFILE;
-
- int negative = 0;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char *progname, *channel;
- char *from_addr, *to_addr;
- FILE *afp, *fopen();
- char line[LINESIZE];
- int cnt, nfields;
- register char *p;
- char *index();
- int gotmatch = 0;
-
-
- progname = *argv++;
-
- if (argv[0][0] == '-' && argv[0][1] == 'f')
- { authfile = argv[1];
- argc -= 2;
- argv += 2;
- }
-
- if (argc < 4)
- { printf("usage: %s [-f authfile] channel from to command [args]\n", progname);
- exit(EX_USAGE);
- }
-
- channel = *argv++;
- from_addr = *argv++;
- to_addr = *argv++;
-
- if ((afp = fopen(authfile, "r")) == NULL)
- { printf("warning: cannot open authorisation file\n");
- gotmatch = 1;
- }
-
- while (!gotmatch && fgets(line, sizeof(line), afp))
- { cnt++;
- if ((p = index(line, '\n')) != NULL)
- *p = '\0';
- if ((p = index(line, '#')) != NULL)
- *p = '\0';
-
- for (p=line; *p == ' ' && *p == '\t'; p++)
- ;
-
- if (*p == '\0')
- continue;
-
- nfields = sscanf(p, "%s %s %s", a_chan, a_from, a_to);
-
- if (nfields != 3)
- { printf("warning: line %d ignored: \"%s\"\n", cnt, line);
- continue;
- }
-
- negative = 0;
- if (strcmp(channel, a_chan) == 0 &&
- match(from_addr, a_from) && match(to_addr, a_to))
- { if (negative > 0)
- gotmatch = -1;
- else
- gotmatch = 1;
- }
-
- #ifdef DEBUG
- printf("%d: %s - %s\n", cnt, line,
- gotmatch ? "matched" : "no match");
- #endif DEBUG
- }
-
- if (gotmatch <= 0)
- { printf("%s: %s is not authorised to send to host/address %s\n",
- progname, from_addr, to_addr);
- exit(EX_NOPERM);
- }
-
- execv(argv[0], argv);
-
- printf("%s: cannot exec %s\n", progname, argv[0]);
- exit(EX_UNAVAILABLE);
- }
-
-
- /*
- * MATCH -- match the strings s1 and s2.
- * s2 can contain wildcards and lists
- */
- match(s1, s2)
- char *s1, *s2;
- {
- char lbuf[ADDRSIZE];
- char *rest, *lp;
- char *index();
-
- if (*s2 == '\\') /* escape */
- { if (*s1 == *(s2+1) && match(s1+1, s2+2))
- return(1);
- }
-
- else if (*s2 == '*') /* wildcard */
- { if (match(s1, ++s2))
- return(1);
-
- while (*s1++)
- { if (match(s1, s2))
- return(1);
- }
- }
-
- else if (*s2 == '{' && (rest = index(++s2, '}'))) /* list */
- { rest++;
- lp = lbuf;
-
- while (s2 != rest)
- { while (*s2 && *s2 != ',' && *s2 != '}')
- *lp++ = *s2++;
- strcpy(lp, rest);
-
- if (match(s1, lbuf))
- return(1);
-
- lp = lbuf;
- s2++;
- }
- }
-
- else if (*s2 == '^') /* negative match */
- { if (match(s1, ++s2))
- { negative++;
- return(1);
- }
- }
-
- else if (*s1 == *s2) /* literal */
- { if (*s1 == '\0')
- return(1);
-
- if (match(++s1, ++s2))
- return(1);
- }
-
- return(0);
- }
-